Eine einfache Einführung in die History-API in JavaScript

Die History-API ist eine dieser JavaScript-Techniken, die jeder Webentwickler kennen muss. Ohne sie springt ein einziger Klick auf die Zurück-Schaltfläche direkt aus Ihrer Anwendung. Sie verlieren alle laufenden Arbeiten und der Benutzer wird gezwungen, von vorne zu beginnen.

Zum Glück gibt es eine einfache Lösung. Seit der Formalisierung von HTML5 (und der Veröffentlichung von Internet Explorer 10) haben wir eine Verlaufs-API, mit der Sie zur Verlaufsliste hinzufügen und auf die Vor- und Zurücknavigation reagieren können. In diesem Artikel erfahren Sie, wie es funktioniert — und probieren es an einem Live-Beispiel aus.

Aber bevor wir fortfahren, schauen wir uns das Problem genauer an.

In den alten Tagen des Webs hat eine Webseite eine Sache getan – Sachen anzuzeigen. Wenn Sie sich etwas anderes ansehen wollten, klickten Sie auf einen Link und gingen zu einer neuen URL.

Als JavaScript immer leistungsfähiger wurde, erkannten die Entwickler, dass jede Webseite eine vollständige Anwendung für sich sein könnte. Eine Webseite könnte mit einer Desktop-Anwendung konkurrieren! Das Problem war, dass die Schaltflächen Zurück und Vorwärts im Browser nicht zu diesem neuen Anwendungsmodell passten. Beispielsweise kann ein Benutzer eine Abfolge von Aufgaben in einer einseitigen Webanwendung ausführen und dann erwarten, dass er die Zurück-Schaltfläche verwendet, um einen einzelnen Schritt zurückzugehen. Stattdessen würde die Zurück-Schaltfläche zur vorherigen Webseite zurückkehren und die JavaScript-App mitten in allem, was sie tat, effektiv herunterfahren.

Oft war dieses Verhalten nicht intuitiv. Stellen Sie sich beispielsweise eine Anwendung vor, die das XMLHttpRequest -Objekt verwendet, um neue Daten abzurufen und die Seite zu aktualisieren. Für den Benutzer könnte es so aussehen, als würde er zu einer neuen Seite reisen. Aber wenn sie den Fehler machen, die Zurück-Taste zu verwenden, wird die Illusion zerstört und alles geht seitwärts.

Werfen wir einen genaueren Blick. Hier ist ein Beispiel, mit dem Sie das Dictionnaire Infernal durchgehen können, ein berühmtes (und jetzt gemeinfreies) Buch aus dem Jahr 1818, in dem seltsame Bestien aus Aberglauben und Mythologie beschrieben werden. Der Trick ist, dass die vorherigen und nächsten Links Sie nicht zu einer anderen Seite führen. Stattdessen lösen sie über XMLHttpRequest einen asynchronen Aufruf aus, der die Informationen für die nächste Folie abruft. Dann aktualisiert der JavaScript-Code das Folienfeld, ohne den Inhalt auf dem Rest der Seite zu stören.

Hier ist eine Live-Version des Beispiels, komplett mit History API-Unterstützung. Obwohl alles auf einer einzigen Webseite stattfindet, können Sie die Vorwärts- und Zurück-Tasten verwenden, um nahtlos von einem Bild zum nächsten zu wechseln. Sie können sogar die Schaltfläche zum erneuten Laden verwenden (lädt die aktuelle Folie neu, anstatt die gesamte App neu zu starten), und Sie können Lesezeichen platzieren, die den aktuellen Status beibehalten.

Und hier ist eine Old-School-Version des Beispiels, die die History-API nicht verwendet. Es spielt keine Rolle, wie weit Sie in der Side—Show sind – wenn Sie die Zurück-Taste verwenden, springen Sie zurück zur vorherigen Webseite. Die Vorwärts- und Nachladetasten sind ähnlich defekt. Lesezeichen Starten Sie die App von Anfang an neu.

Sie können den gesamten Quellcode hier herunterladen, um damit zu spielen. (Es funktioniert jedoch nicht lokal, da es das XMLHttpRequest -Objekt verwendet, um Webanforderungen zu stellen.) Im Rest dieses Artikels werde ich aufschlüsseln, wie alles funktioniert.

Vorbereiten des Beispiels

Bevor wir in die History API einsteigen, ist es wichtig, ein grundlegendes Verständnis davon zu haben, wie dieses Beispiel funktioniert. Es ist alles ziemlich einfach.

Die Seite verwendet eine Nummer, um die aktuell angezeigte Folie zu verfolgen. Wenn Sie auf Weiter oder Zurück klicken, ändert der Code die aktuelle Foliennummer. Dann verwendet es seine eigene goToSlide() Funktion, um die Seite zu aktualisieren.

In der goToSlide() Funktion findet die eigentliche Arbeit statt. Es startet eine asynchrone Anfrage mit dem berüchtigten XMLHttpRequest Objekt.

Sie entscheiden, wie der Folieninhalt generiert und an den aufrufenden Code auf der Seite zurückgesendet wird. Normalerweise haben Sie eine Art Routing-Framework, das den richtigen serverseitigen Code auslöst. Dieser serverseitige Code kann dann den Folieninhalt aus einem Cache, einer Datenbank, einer Datei oder sogar einem fest codierten Markupblock abrufen.

In diesem Beispiel habe ich die Dinge so einfach wie möglich gehalten. Die Anforderung erfasst das HTML-Markup aus einer statischen Datei. Wenn Sie also die dritte Folie anfordern (mit einer relativen URL wie Slides / 3 ), erhalten Sie nur für diese Folie ein HTML-Markup-Snippet. Ganz ruhig!

Wenn die Anforderung beendet ist, löst der Browser den newSlideReceived() Ereignishandler aus. Dann geht es einfach darum, das empfangene Markup mit einem Platzhalter <div> in die Seite einzufügen.

Das ist alles, was Sie wissen müssen, um die naive Version dieser Seite zu erstellen, die den Browserverlauf nicht unterstützt.

Das History-Objekt

Das history -Objekt existiert fast seit den Anfängen von JavaScript. Aber für einen Großteil seines Lebens war es weit weniger mächtig (und weit weniger nützlich) als heute.

Das ursprüngliche history Objekt hat nur eine Eigenschaft und drei grundlegende Methoden. Die Eigenschaft lautet length und zeigt an, wie viele Einträge in der Verlaufsliste des Browsers enthalten sind:

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

Dieses Detail ist größtenteils nutzlos.

Die drei ursprünglichen history Methoden sind back() (sendet einen Besucher einen Schritt zurück im Browserverlauf), forward() (sendet einen Besucher einen Schritt vorwärts) und go() (nimmt einen numerischen Offset, der dem Browser mitteilt, wie viele schritte vorwärts oder rückwärts). All dies summiert sich zu relativ wenig, es sei denn, Sie möchten Ihre eigenen benutzerdefinierten Vor- und Zurück-Schaltflächen auf einer Webseite entwerfen.

Die HistoryAPI fügt zwei viel nützlichere Zutaten hinzu: die pushState() Methode und das onPopState Ereignis.

Hinzufügen eines Eintrags zur History-Liste

Die pushState()-Methode ist das Herzstück der History-API. Sie können der Verlaufsliste für die aktuelle Seite ein neues Element hinzufügen. So sieht das aus:

An dieser Stelle fragen Sie sich vielleicht — was bringt es, mehr als einen Eintrag für dieselbe Seite zu haben? Der Trick besteht darin, dass jedem Eintrag ein Status zugeordnet ist — eine verknüpfte Information oder ein von Ihnen festgelegtes Objekt. Wenn der Benutzer durch die Verlaufsliste zurückschreitet, erhalten Sie die entsprechenden Statusinformationen, sodass Sie die Seite auf die vorherige Version zurücksetzen können.

Die pushState() Methode benötigt drei Argumente:

  • Data. Das erste Argument sind alle Daten, die Sie speichern möchten, um den aktuellen Status dieser Seite darzustellen. Sie verwenden diese Informationen, um die Seite wiederherzustellen, wenn der Benutzer die Verlaufsliste durchläuft.
  • Titel. Das zweite Argument ist der Seitentitel, den der Browser anzeigen soll. Derzeit ignorieren alle Browser dieses Detail. (Sie können also einfach null .)
  • URL. Das dritte Argument ist die neue Version der URL, die Sie für die Seite in der Adressleiste des Browsers anzeigen möchten. Auf diese Weise können Sie die Schaltfläche zum erneuten Laden und die Browser-Lesezeichen besser unterstützen.

Im Dictionnaire Infernal Slideshow-Beispiel ist es einfach, den Verlauf hinzuzufügen, da Sie nur die Foliennummer im Auge behalten müssen. Sie fügen der Verlaufsliste jedes Mal hinzu, wenn sich die Folie ändert.

Hier ist die Codezeile, die Sie hinzufügen müssen:

history.pushState(slideNumber, null, null);

Sie werden feststellen, dass dieser Code den Seitentitel mit dem zweiten Argument nicht ändert (weil es sowieso nicht funktioniert) und die URL nicht ändert (Sie werden gleich sehen, wie das geht). Alles, was es tut, ist die Foliennummer zu speichern.

Für das vollständige Bild sind hier die beiden Aufrufe von history.pushState() an der richtigen Stelle – die Ereignishandler für die nächsten und vorherigen Links:

Rückkehr zu einer vorherigen Seite

Wenn Sie die pushState() -Methode verwenden, müssen Sie auch über ihr natürliches Gegenstück nachdenken, das onPopState -Ereignis. Während die pushState() -Methode einen neuen Eintrag in die Verlaufsliste des Browsers einfügt, gibt Ihnen das onPopState -Ereignis die Möglichkeit, damit umzugehen, wenn der Benutzer zurückkehrt.

Um zu verstehen, wie dies funktioniert, überlegen Sie, was passiert, wenn ein Besucher alle Folien im Beispiel Dictionnaire Infernal durchläuft. Wenn jede neue Folie geladen wird, fügt die Seite einen Verlaufseintrag hinzu. Wenn der Benutzer jedoch mit der Zurück-Taste zurücktritt, passiert nichts.

Um dieses Manko zu beheben, müssen Sie das onPopState -Ereignis behandeln, das nach jeder Verlaufsnavigation ausgelöst wird. (Dies gilt auch, wenn Sie eine der Verlaufsmethoden verwenden, z. B. history.back(), sowie wenn der Benutzer auf die Navigationsschaltflächen des Browsers klickt.)

Das onPopState -Ereignis liefert Ihrem Code die Statusinformationen, die Sie zuvor mit pushState() gespeichert haben. In diesem Fall ist das nur die Foliennummer, die Sie aus der state Eigenschaft des Ereignisarguments abrufen können:

var slideNumber = e.State;

Ihre Aufgabe ist es, die Statusinformationen zu verwenden, um die richtige Version der Seite wiederherzustellen. Im aktuellen Beispiel bedeutet dies, dass die entsprechende Folie geladen wird, indem die praktische goToSlide() -Funktion aufgerufen wird, die die gesamte Foliennavigation übernimmt. Der komplette Code ist kurz und unkompliziert:

Beachten Sie, dass Sie überprüfen müssen, ob e.Statenull ist, was bei einigen Browsern der Fall ist, wenn die Seite zum ersten Mal geladen wird und kein Status gespeichert ist.

URL ändern

Die aktuelle Version dieses Beispiels unterstützt die Verlaufsliste, funktioniert aber nicht gut mit der Schaltfläche zum erneuten Laden. Wenn Sie sich beispielsweise zur dritten Folie durchklicken und dann die Seite aktualisieren, kehren Sie zum Anfang zurück. Sie befinden sich in derselben Situation, wenn Sie versuchen, eine der Folien mit einem Lesezeichen zu versehen.

Die Lösung für diese Probleme besteht darin, die History-API zu verwenden, um die URL zu ändern. Aber es gibt einen wichtigen Grund, warum ich diesen Schritt bis zuletzt belassen habe. Beispiele, die die History-API verwenden, ändern häufig die URL, verwenden jedoch nicht die neue URL. Dies kann zu einer Webanwendung führen, die beim Aktualisieren durch den Benutzer unterbrochen wird (mit einem hässlichen 404-Fehler) oder zu einer ähnlichen, aber geringfügig anderen Version der Seite wechselt. Wenn Sie nicht sicher sind, wie Sie mit verschiedenen URLs umgehen sollen, ist es keine Schande, den vereinfachten Ansatz aus dem vorherigen Beispiel zu verwenden.

Nehmen wir also an, Sie sind bereit, einzutauchen, bessere URLs zu erstellen und mit Lesezeichen und Browseraktualisierungen gut zu spielen. Es gibt zwei grundlegende Ansätze:

  • Ändern Sie den URL-Seitennamen insgesamt. Im Beispiel Dictionnaire Infernal können Sie die URL in Slide1 ändern.html, Slide2.html und so weiter, während sich der Benutzer durch die Folien bewegt. Der Haken ist, dass Sie entweder tatsächliche Seiten mit diesen Namen haben müssen (tun Sie das nicht, es ist umständlich), oder Sie müssen das Routing so einrichten, dass Ihr Webserver eine Anforderung für Slide2 erhält.html Es wird Code ausgeführt, der die richtige Version der Seite erstellt.
  • Behalten Sie denselben Seitennamen bei, fügen Sie der Abfragezeichenfolge jedoch Informationen hinzu. Dies ist ein einfacherer, kleinerer Ansatz. Wenn der Benutzer durch die Diashow reist, erhalten Sie URLs wie SlideShow.html?slide=1, dann Diashow.html?slide=2, Diashow.html?slide = 3 und so weiter. Der Vorteil dieses Ansatzes besteht darin, dass es trivial einfach ist, ein kleines Stück JavaScript zu schreiben, das die Abfragezeichenfolge überprüft und sicherstellt, dass Sie sich beim erneuten Laden der Seite auf der richtigen Folie befinden. Sie benötigen keinen Servercode, damit dies funktioniert – eine Seite kann alles.

Hier ist eine modifizierte Version des pushState() Aufrufs, den Sie zuvor gesehen haben und der den zweiten Ansatz verwendet. Dieser Code stopft die Foliennummer an das Ende der URL:

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

Und hier ist der Code, der ausgeführt wird, wenn die Seite neu geladen wird. Es sucht nach den Folieninformationen in der URL und ruft — wenn es eine richtige Nummer findet – die Funktion goToSlide() auf, um die Folie zu laden.

Jetzt werden Sie nie Ihren Platz in der Diashow verlieren. Sie können die vollständige Version dieses Beispiels ausprobieren oder alles hier herunterladen.

Letzte Details

Die History-API ist einfach zu bedienen, macht es aber auch einfach, größere Probleme zu erstellen, die Sie lösen. Jetzt, da Sie wissen, wie alles zusammenpasst, Hier sind einige letzte Ratschläge:

  • Wenn Sie drücken, müssen Sie Pop. Die pushState() Methode und onPopState Ereignis sind Partner. Was du mit dem einen eingibst, bekommst du mit dem anderen zurück.
  • Ändern Sie die URL nicht, es sei denn, Sie sind bereit, damit umzugehen. Es ist schön, Ihre URL zu ändern, um Ihre sich ändernde Seite widerzuspiegeln, aber Sie müssen in der Lage sein, Anforderungen für jede von Ihnen verwendete URL zu verarbeiten. Wenn Ihre URL auf eine nicht vorhandene Seite verweist, wird Ihre Anwendung bei Aktualisierungen und Lesezeichen unterbrochen.
  • Verwenden Sie ein benutzerdefiniertes Statusobjekt, um weitere Informationen zu speichern. Sie müssen sich nicht an eine einfache Nummer halten. Sie können ein gesamtes benutzerdefiniertes Objekt in den Status versetzen, der alle Informationen bündeln kann, die Sie für eine komplexe Aufgabe benötigen.



Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.