proste wprowadzenie do historii API w JavaScript

Historia API jest jedną z tych technik JavaScript, które każdy Web developer musi znać na zimno. Bez tego jedno kliknięcie przycisku Wstecz wyskoczy prosto z aplikacji. Stracisz wszelkie prace w toku, a użytkownik będzie zmuszony zacząć wszystko od nowa.

na szczęście jest proste rozwiązanie. Od czasu sformalizowania HTML5 (i wydania Internet Explorer 10) mamy interfejs API historii, który pozwala dodawać do listy historii i reagować na nawigację Wstecz i do przodu. W tym artykule dowiesz się, jak to działa — i wypróbujesz go na żywym przykładzie.

ale zanim przejdziemy dalej, przyjrzyjmy się bliżej problemowi.

w dawnych czasach w sieci strona internetowa robiła jedną rzecz-wyświetlała rzeczy. Kiedy chciałeś spojrzeć na coś innego, kliknąłeś link i przeszedłeś do nowego adresu URL.

wraz z rozwojem JavaScript, Programiści zdali sobie sprawę, że każda strona internetowa może być kompletną aplikacją samą w sobie. Strona internetowa może konkurować z aplikacją desktopową! Problem polegał na tym, że przyciski do tyłu i do przodu w przeglądarce nie pasowały do tego nowego modelu aplikacji. Na przykład użytkownik może wykonać sekwencję zadań w jednostronicowej aplikacji internetowej, a następnie oczekiwać, że użyje przycisku Wstecz, aby cofnąć się o jeden krok. Zamiast tego przycisk Wstecz powróci do poprzedniej strony internetowej, skutecznie zamykając aplikację JavaScript w środku tego, co robiła.

często takie zachowanie nie było intuicyjne. Na przykład rozważ aplikację, która używa obiektuXMLHttpRequest do pobierania nowych danych i aktualizacji strony. Dla użytkownika może to wyglądać, jakby podróżował do nowej strony. Ale jeśli popełnią błąd używając przycisku Wstecz, iluzja zostanie rozbita i wszystko pójdzie na boki.

przyjrzyjmy się bliżej. Oto przykład, który pozwoli Ci przejść przez Dictionnaire Infernal, słynną (a teraz domenę publiczną) książkę z 1818 roku opisującą dziwne bestie z przesądów i mitologii. Sztuczka polega na tym, że poprzednie i następne linki nie przenoszą Cię na inną stronę. Zamiast tego wywołują asynchroniczne wywołanie poprzez XMLHttpRequest, które pobiera informacje dla następnego slajdu. Następnie kod JavaScript aktualizuje pole slajdów, nie naruszając treści na pozostałej części strony.

oto aktualna wersja przykładu, wraz z obsługą API historii. Mimo że wszystko odbywa się na jednej stronie internetowej, możesz użyć przycisków do przodu i do tyłu, aby płynnie przejść od jednego obrazu do drugiego. Możesz nawet użyć przycisku Przeładuj (przeładowuje bieżący slajd, zamiast ponownie uruchamiać całą aplikację), a także umieścić zakładki, które zachowują aktualny stan — innymi słowy, prowadzą prosto do slajdu, na który aktualnie patrzysz.

a oto stara wersja przykładu, która nie używa API historii. Nie ma znaczenia, jak daleko jesteś w pokazie bocznym – po użyciu przycisku Wstecz, przeskakujesz z powrotem do poprzedniej strony. Przyciski Forward I Reload są podobnie uszkodzone. Zakładki uruchom ponownie aplikację od początku.

możesz pobrać cały kod źródłowy tutaj do zabawy. (Jednak nie będzie działać lokalnie, ponieważ używa obiektuXMLHttpRequest do wysyłania żądań internetowych.) W dalszej części tego artykułu omówię, jak wszystko działa.

przygotowanie przykładu

zanim przejdziemy do historii API, ważne jest, aby mieć podstawową wiedzę na temat tego, jak ten przykład działa. To całkiem proste.

strona używa numeru, aby śledzić slajd, który jest aktualnie wyświetlany. Po kliknięciu przycisku Next lub Previous kod zmienia bieżący numer slajdu. Następnie używa własnej funkcjigoToSlide() do aktualizacji strony.

funkcja goToSlide() jest miejscem, w którym odbywa się prawdziwa praca. Uruchamia ono asymetryczne żądanie używając niesławnego obiektu XMLHttpRequest.

to Ty decydujesz, w jaki sposób zawartość slajdu zostanie wygenerowana i odesłana do kodu wywołującego na stronie. Zazwyczaj masz jakiś rodzaj struktury routingu, która uruchamia odpowiedni kod po stronie serwera. Ten kod po stronie serwera może następnie pobrać zawartość slajdu z pamięci podręcznej, bazy danych, Pliku, a nawet zakodowanego bloku znaczników.

w tym przykładzie trzymałem rzeczy tak proste, jak to tylko możliwe. Żądanie pobiera znaczniki HTML z pliku statycznego. Jeśli więc żądasz trzeciego slajdu (z względnym adresem URL, takim jak Slides/3), otrzymasz fragment znaczników HTML dla tego slajdu. Spokojnie!

Po zakończeniu żądania przeglądarka uruchamia obsługę zdarzenianewSlideReceived(). Następnie wystarczy wziąć otrzymany znacznik i wstawić go na stronę, używając symbolu zastępczego <div>.

to wszystko, co musisz wiedzieć, aby zbudować naiwną wersję tej strony, która nie obsługuje historii przeglądarki.

obiekt history

obiekthistory istnieje niemal od zarania JavaScript. Ale przez większą część swojego życia był znacznie mniej potężny (i znacznie mniej użyteczny) niż jest dzisiaj.

oryginalny history obiekt posiada tylko jedną właściwość i trzy podstawowe metody. Właściwość to length I informuje, ile wpisów znajduje się na liście historii przeglądarki:

alert("You have " + history.length + " pages in the history.");

ten szczegół jest w większości bezużyteczny.

trzy oryginalne metody history to back() (wysyła odwiedzającego o krok do tyłu w historii przeglądania), forward() (wysyła odwiedzającego o krok do przodu) i go() (pobiera przesunięcie liczbowe, które informuje przeglądarkę, ile kroków należy wykonać do przodu lub do tyłu). Wszystko to składa się na stosunkowo niewiele, chyba że chcesz zaprojektować własne niestandardowe przyciski do tyłu i do przodu na stronie internetowej.

Historiapi dodaje dwa znacznie bardziej przydatne składniki: metodę pushState() oraz Zdarzenie onPopState.

dodanie wpisu do listy historii

metodapushState() jest centralnym elementem API historii. Umożliwia dodanie nowego elementu do listy historii bieżącej strony. Oto jak to wygląda:

w tym momencie możesz się zastanawiać — po co mieć więcej niż jeden wpis na tej samej stronie? Sztuczka polega na tym, że każdy wpis ma dołączony jakiś stan — powiązaną informację lub obiekt, który ustawiłeś. Gdy użytkownik cofnie się przez listę historii, otrzymasz odpowiednie informacje o stanie, dzięki czemu możesz powrócić do poprzedniej wersji strony.

metoda pushState() pobiera trzy argumenty:

  • dane. Pierwszym argumentem jest dowolny fragment danych, który chcesz zapisać, aby reprezentować bieżący stan tej strony. Wykorzystasz te informacje do przywrócenia strony, gdy użytkownik powróci do listy historii.
  • Tytuł. Drugim argumentem jest tytuł strony, który ma być wyświetlany przez przeglądarkę. Obecnie wszystkie przeglądarki są ujednolicone w ignorowaniu tych szczegółów. (Możesz więc po prostu przekazać null.)
  • URL. Trzeci argument to nowa wersja adresu URL, który chcesz wyświetlić dla strony w pasku adresu przeglądarki. Pozwala to dodać lepszą obsługę przycisku przeładowania i zakładek przeglądarki.

w przykładzie pokazu slajdów Dictionnaire Infernal łatwo jest dodać obsługę historii, aby śledzić tylko numer slajdu. Dodajesz do listy historii za każdym razem, gdy slajd się zmienia.

oto wiersz kodu, który musisz dodać:

history.pushState(slideNumber, null, null);

zauważysz, że ten kod nie zmienia tytułu strony z drugim argumentem (ponieważ i tak nie działa) i nie zmienia adresu URL (zobaczysz, jak to zrobić za chwilę). Wszystko, co robi, to zapisuje numer slajdu.

aby uzyskać pełny obraz, oto dwa wywołania dohistory.pushState() w odpowiednim miejscu — obsługa zdarzeń dla następnego i poprzedniego łącza:

powrót do poprzedniej strony

Kiedy używasz metodypushState(), musisz również pomyśleć o jej naturalnym odpowiedniku, zdarzeniuonPopState. Podczas gdy metodapushState()umieszcza nowy wpis na liście historii przeglądarki, ZdarzenieonPopState daje Ci możliwość radzenia sobie z nim, gdy użytkownik powróci.

aby zrozumieć, jak to działa, zastanów się, co się stanie, jeśli odwiedzający przejdzie przez wszystkie slajdy w przykładzie Dictionnaire Infernal. Gdy każdy nowy slajd jest ładowany, strona dodaje wpis historii. Ale jeśli użytkownik cofnie się za pomocą przycisku Wstecz, nic się nie dzieje.

aby naprawić ten błąd, musisz obsłużyć ZdarzenieonPopState, które jest wyzwalane po każdej nawigacji historii. (Dotyczy to również sytuacji, gdy korzystasz z jednej z metod historii, takich jak history.back(), a także gdy użytkownik kliknie przyciski nawigacji w przeglądarce.)

ZdarzenieonPopStatedostarcza Twojemu kodowi informacje o stanie zapisane wcześniej za pomocą pushState(). W tym przypadku jest to tylko numer slajdu, który możesz pobrać zstate właściwości argumentu event, tak jak:

var slideNumber = e.State;

Twoim zadaniem jest użycie informacji o stanie w celu przywrócenia właściwej wersji strony. W bieżącym przykładzie oznacza to wczytanie odpowiedniego slajdu przez wywołanie przydatnej funkcjigoToSlide(), która obsługuje wszystkie nawigacje po slajdzie. Kompletny kod jest krótki i prosty:

zauważ, że musisz sprawdzić, czy tonull, co dzieje się w niektórych przeglądarkach, gdy strona jest ładowana po raz pierwszy i nie ma zapisanego stanu.

zmiana adresu URL

aktualna wersja tego przykładu obsługuje listę historii, ale nie gra dobrze z przyciskiem Przeładuj. Na przykład, jeśli klikniesz na trzeci slajd, a następnie odświeżysz stronę, skończysz z powrotem na początku. Znajdziesz się w tej samej sytuacji, jeśli spróbujesz dodać do zakładki jeden ze slajdów-wróć do zakładki, A zaczniesz z powrotem od pierwszego slajdu.

rozwiązaniem tych problemów jest użycie API historii do modyfikacji adresu URL. Ale jest ważny powód, dla którego zostawiłem ten krok do końca. Często przykłady, które używają interfejsu API Historia, zmieniają adres URL, ale nie używają nowego adresu URL. Może to prowadzić do awarii aplikacji internetowej, gdy użytkownik odświeży ją (z brzydkim błędem 404) lub przejdzie do podobnej, ale nieco innej wersji strony. Jeśli nie jesteś pewien, jak obsługiwać różne adresy URL, nie ma wstydu w użyciu uproszczonego podejścia z poprzedniego przykładu.

powiedzmy, że jesteś gotowy do nurkowania, tworzenia lepszych adresów URL i przyjemnej gry z zakładkami i odświeżania przeglądarki. Istnieją dwa podstawowe podejścia, które możesz zastosować:

  • Zmień całkowicie nazwę strony URL. W przykładzie Dictionnaire Infernal możesz zmienić adres URL na Slide1.html, Slide2.html i tak dalej, gdy użytkownik porusza się po slajdach. Haczyk polega na tym, że musisz albo mieć rzeczywiste strony o tych nazwach (nie rób tego, jest to uciążliwe), albo musisz skonfigurować routing, aby gdy twój serwer WWW otrzyma żądanie Slide2.html uruchamia kod, który tworzy odpowiednią wersję strony.
  • zachowuje tę samą nazwę strony, ale dodaje informacje do ciągu zapytania. Jest to prostsze podejście na mniejszą skalę. Gdy użytkownik będzie podróżował po pokazie slajdów, otrzymasz adresy URL, takie jak pokaz slajdów.html?slide=1, następnie SlideShow.html?slide=2, pokaz slajdów.html?slide=3 i tak dalej. Zaletą tego podejścia jest to, że trywialnie łatwo jest napisać mały kawałek JavaScript, który sprawdza ciąg zapytania i upewnia się, że jesteś na prawym slajdzie, gdy strona jest przeładowywana. Nie potrzebujesz żadnego kodu serwera, aby to działało-jedna strona może zrobić to wszystko.

oto zmodyfikowana wersjapushState() wywołania, które widziałeś wcześniej, które używa drugiego podejścia. Ten kod umieszcza numer slajdu na końcu adresu URL:

history.pushState(slide, null, "Dictionnaire.html?slide=" + slide);

i oto kod uruchamiany po przeładowaniu strony. Sprawdza informacje o slajdzie w adresie URL i — jeśli znajdzie właściwy numer-wywołuje funkcję goToSlide(), aby załadować slajd.

teraz już nigdy nie stracisz miejsca w pokazie slajdów. Możesz wypróbować pełną wersję tego przykładu lub pobrać wszystko tutaj.

szczegóły końcowe

interfejs API historia jest łatwy w użyciu, ale także ułatwia tworzenie większych problemów, które rozwiązujesz. Teraz, gdy wiesz, jak wszystko do siebie pasuje, oto kilka ostatnich rad:

  • jeśli naciskasz, musisz pop. Partnerem wydarzenia jestpushState() orazonPopState. Co włożysz do jednego, wrócisz do drugiego.
  • nie zmieniaj adresu URL, chyba że jesteś gotowy do obsługi. Dobrze jest zmienić adres URL, aby odzwierciedlał zmieniającą się Stronę, ale musisz być w stanie obsługiwać żądania dla każdego używanego adresu URL. Jeśli twój adres URL wskazuje na stronę, która nie istnieje, aplikacja zostanie przerwana podczas odświeżania i zakładek.
  • Użyj niestandardowego obiektu stanu, aby zapisać więcej informacji. Nie musisz trzymać się prostej liczby. Możesz umieścić cały obiekt niestandardowy w stanie, który może połączyć wszystkie informacje potrzebne do złożonego zadania.



Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.