Scott Tiger Tech Blog

Blog technologiczny firmy Scott Tiger S.A.

History API

Autor: Piotr Karpiuk o wtorek 7. Sierpień 2012

Przycisk „Wstecz” w przeglądarce niezbyt dobrze wpisuje się w świat współczesnych webowych aplikacji AJAXowych, które raczej już nie przeładowują całych stron, poprzestając na aktualizowaniu fragmentów drzewa DOM. Również pojęcie zakładki (ang. bookmark) w przypadku aplikacji Web 2.0 odnosi się do całej aplikacji, a nie jej stanu który dałoby się w postaci URLa przesłać koledze i odtworzyć na innym komputerze.

Wyobraźmy sobie że piszemy nowoczesną aplikację webową http://gallery.com służącą do wyświetlania galerii kolejno prezentowanych zdjęć, być może z jakimiś efektami. Obrazy mają być przesyłane AJAXem i podmieniane, bez przeładowywania całej strony. Wchodzące w skład standardu HTML5 History API pozwala zaprogramować aplikację tak, aby przycisk „Wstecz” przeglądarki wyświetlał poprzednie zdjęcie (zamiast kończyć pracę całej aplikacji i przechodzić do wcześniej oglądanej witryny, np. onet.pl). Co więcej, z chwilą wyświetlenia każdego obrazka będzie zmieniał się URL pokazywany w pasku adresu przeglądarki, dzięki czemu można takiego URLa wysłać koledze aby mógł od razu przejść do konkretnego zdjęcia, albo zrobić zakładkę. Takie rozwiązanie uczyni aplikację bardziej użyteczną i intuicyjną dla użytkownika przyzwyczajonego do witryn starego typu.

Po załadowaniu obrazka z URLa http://image?id=145 i wyświetleniu go użytkownikowi, aplikacja wykonuje polecenie:

        window.history.pushState(
          { imgURL: 'http://gallery.com/image?id=145' },
          null,
          'http://gallery.com/show_image?id=145'
        );

Tworzy ono nowy rekord na końcu listy historii sesji przeglądarki, i czyni ten rekord aktywnym. Z rekordem tym związany jest dowolny zdefiniowany przez programistę stan (pierwszy parametr wywołania) oraz URL (ostatni parametr), przy czym URL jest wyświetlany w pasku adresu przeglądarki, ale przeglądarka nie ładuje tego URLa ani nie sprawdza czy odnosi się do prawdziwego zasobu. Ten link z paska przeglądarki jest po to, żeby można go było wysłać koledze.

Po obejrzeniu kilku zdjęć, na stosie historii pojawi się kilka rekordów. Gdy teraz użytkownik naciśnie przycisk „Wstecz” przeglądarki, przeglądarka uczyni aktywnym poprzedni rekord listy historii (w tym ustawi window.location), wyświetli odpowiadający mu URL w pasku adresu (ale nie będzie ładować zasobu spod tego URLa), po czym nastąpi zdarzenie popstate:

        window.onpopstate = function( e ) {
          var imgSrc = e.state.imgURL;
          // pokazujemy obrazek o URLu imgSrc
        };
      

Zwróćmy uwagę na jedną rzecz: w pasku URL przeglądarki wyświetlamy inny URL niż ten, z którego korzystamy przy wyświetlaniu zdjęcia w aplikacji. Jest tak, ponieważ zadaniem tego pierwszego URLa jest załadowanie całej aplikacji webowej i przejście do określonego obrazka, a pod drugim URLem ukrywa się sam obrazek.

Kilka uwag na koniec:

  • środkowy parametr wywołania metody pushState() nosi nazwę title i nie jest obecnie do niczego wykorzystywany,
  • URL z ostatniego parametru pushState() musi mieć to samo pochodzenie (ang. origin, czyli protokół, host i port) co URL aplikacji webowej,
  • oprócz metody pushState() jest jeszcze replaceState() przyjmująca te same parametry, lecz modyfikuje bieżący rekord na liście historii sesji, a nie dodaje nowy,
  • obiekt window.history ma jeszcze metody back() i forward(), których wywołanie odpowiada naciśnięciu przycisków „Wstecz” i „Naprzód” przeglądarki, a także metodę go() przyjmującą parametr całkowitoliczbowy, przy czym -1 odpowiada wywołaniu back(), a +1 wywołaniu forward(),
  • jeżeli spodobało Ci się History API w HTML5 i chciałbyś móc skorzystać z jego dobrodziejstw także w starszych przeglądarkach, użyj biblioteki history.js.

Share and Enjoy:
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Śledzik
  • Blip
  • Blogger.com
  • Gadu-Gadu Live
  • LinkedIn
  • MySpace
  • Wykop

Zostaw komentarz

XHTML: Możesz użyć następujących tagów: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>