Een eenvoudige introductie tot de geschiedenis API in JavaScript

De geschiedenis API is een van die JavaScript technieken die elke webontwikkelaar nodig heeft om koud te weten. Zonder dat, een enkele klik van de knop terug springt direct uit uw toepassing. Je verliest alle lopende werk, en de gebruiker zal worden gedwongen om helemaal opnieuw te beginnen.

gelukkig is er een eenvoudige oplossing. Sinds de formalisering van HTML5 (en de release van Internet Explorer 10), we hebben een geschiedenis API waarmee u toevoegen aan de lijst geschiedenis en reageren op terug en vooruit navigatie. In dit artikel leer je hoe het werkt — en probeer je het uit met een live voorbeeld.

maar voordat we verder gaan, laten we het probleem nader bekijken.

In de oude dagen van het web deed een webpagina één ding: dingen weergeven. Wanneer u iets anders wilde bekijken, klikte u op een link en ging naar een nieuwe URL.

naarmate JavaScript krachtiger werd, realiseerden ontwikkelaars zich dat elke webpagina een complete toepassing op zichzelf kon zijn. Een webpagina kan concurreren met een desktop applicatie! Het probleem was dat de terug – en Vooruitknoppen in de browser niet in dit nieuwe toepassingsmodel pasten. Een gebruiker kan bijvoorbeeld een reeks taken uitvoeren in een webtoepassing met één pagina en dan verwachten dat hij de knop Terug gebruikt om een enkele stap terug te gaan. In plaats daarvan, de terug knop zou terugkeren naar de vorige webpagina, effectief afsluiten van de JavaScript-app in het midden van wat het deed.

vaak was dit gedrag niet intuïtief. Overweeg bijvoorbeeld een toepassing die het XMLHttpRequest object gebruikt om nieuwe gegevens op te halen en de pagina bij te werken. Voor de gebruiker kan het lijken alsof ze naar een nieuwe pagina reizen. Maar als ze de fout maken om de Back-knop te gebruiken, is de illusie verbrijzeld en gaat alles zijwaarts.

laten we een kijkje nemen. Hier is een voorbeeld dat laat je stap door de Dictionnaire Infernal, een beroemd (en nu publiek domein) boek uit 1818 beschrijven vreemde beesten uit bijgeloof en mythologie. De truc is dat de vorige en volgende links je niet naar een andere pagina. In plaats daarvan activeren ze een asynchrone aanroep via XMLHttpRequest die de informatie voor de volgende dia krijgt. Vervolgens werkt de JavaScript-code de slide box bij, zonder de inhoud op de rest van de pagina te verstoren.

Hier is een live versie van het voorbeeld, compleet met geschiedenis API ondersteuning. Hoewel alles in één webpagina plaatsvindt, kunt u de knoppen vooruit en terug gebruiken om naadloos van de ene afbeelding naar de volgende te stappen. U kunt zelfs gebruik maken van de Herlaadknop (herlaadt de huidige dia, in plaats van de hele app opnieuw op te starten), en u kunt bladwijzers die de huidige staat te houden plaatsen — met andere woorden, ze leiden u direct terug naar de dia die u momenteel op zoek bent naar.

en hier is een old-school versie van het voorbeeld die de History API niet gebruikt. Het maakt niet uit hoe ver je bent in de side show — wanneer u de Back-knop te gebruiken, je springt terug naar de vorige webpagina. De Vooruit-en Herlaadknoppen zijn eveneens gebroken. Bladwijzers Herstart de app vanaf het begin.

u kunt hier alle broncode downloaden om mee te spelen. (Het zal echter niet lokaal werken, omdat het het XMLHttpRequest object gebruikt om webverzoeken te doen.) In de rest van dit artikel, Ik zal breken hoe alles werkt.

het voorbeeld voorbereiden

voordat we in de History API gaan, is het belangrijk om een basiskennis te hebben van hoe dit voorbeeld werkt. Het is allemaal vrij simpel.

de pagina gebruikt een nummer om de dia bij te houden die op dit moment wordt getoond. Wanneer u op Volgende of vorige klikt, verandert de code het huidige slidenummer. Vervolgens gebruikt het zijn eigen goToSlide() functie om de pagina bij te werken.

de goToSlide() functie is waar het echte werk plaatsvindt. Het Start een asychrone verzoek met behulp van het beruchte XMLHttpRequest object.

Het is aan u om te beslissen hoe de dia-inhoud wordt gegenereerd en teruggestuurd naar de aanroepende code in de pagina. Meestal heb je een soort van routing framework dat de juiste server-side code activeert. Die server-side code kan dan pak de dia-inhoud van een cache, een database, een bestand, of zelfs een hard-gecodeerde blok van markup.

in dit voorbeeld heb ik de dingen zo eenvoudig mogelijk gehouden. Het verzoek pakt de html-opmaak uit een statisch bestand. Dus als je de derde dia aanvraagt (met een relatieve URL zoals Slides/3), krijg je een fragment van HTML-opmaak voor alleen die dia. Rustig!

wanneer het verzoek is voltooid, activeert de browser de newSlideReceived() event handler. Dan is het gewoon een kwestie van het nemen van de ontvangen markup en het invoegen in de pagina, met behulp van een plaatshouder <div>.

dat is alles wat u moet weten om de naïeve versie van deze pagina te bouwen, die geen browsergeschiedenis ondersteunt.

het geschiedenisobject

het history object bestaat bijna sinds het begin van JavaScript. Maar voor een groot deel van zijn leven was het veel minder krachtig (en veel minder nuttig) dan het nu is.

het oorspronkelijkehistory object heeft slechts één eigenschap en drie basismethoden. De eigenschap is length, en het vertelt u hoeveel items er in de geschiedenislijst van de browser staan:

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

Dit detail is meestal nutteloos.

De drie oorspronkelijke history methoden zijn back() (stuurt een bezoeker een stap terug in de browsegeschiedenis), forward() (stuurt een bezoeker een stap vooruit) en go() (neemt een numerieke verschuiving die de browser vertelt hoeveel stappen vooruit of achteruit te gaan). Dit alles komt neer op relatief weinig, tenzij u wilt uw eigen aangepaste back en forward knoppen op een webpagina te ontwerpen.

De HistoryAPI voegt twee veel meer bruikbare ingrediënten toe: de pushState() methode en de onPopState gebeurtenis.

een item toevoegen aan de geschiedenislijst

de methode pushState() is het middelpunt van de Geschiedenisapi. Hiermee kunt u een nieuw item toevoegen aan de geschiedenislijst voor de huidige pagina. Zo ziet het eruit:

Op dit punt kun je je afvragen — wat is het nut van meer dan één regel voor dezelfde pagina? De truc is dat elk item een bepaalde staat heeft die ermee verbonden is-een gekoppeld stuk informatie of object dat je instelt. Wanneer de gebruiker teruggaat door de geschiedenislijst, krijgt u de bijbehorende statusinformatie, zodat u de pagina naar de vorige versie kunt terugsturen.

de pushState() methode heeft drie argumenten:

  • Data. Het eerste argument is elk stukje gegevens dat u wilt opslaan om de huidige status van deze pagina weer te geven. U zult deze informatie gebruiken om de pagina te herstellen wanneer de gebruiker teruggaat door de geschiedenislijst.
  • Titel. Het tweede argument is de paginatitel die de browser moet tonen. Momenteel zijn alle browsers verenigd in het negeren van dit detail. (U kunt dus gewoon nulldoorgeven.)
  • URL. Het derde argument is de nieuwe versie van de URL die u wilt weergeven voor de pagina in de adresbalk van de browser. Hiermee kunt u betere ondersteuning toevoegen voor de Herlaadknop en browser bladwijzers.

in het Dictionnaire Infernal slideshow voorbeeld, is het eenvoudig om geschiedenis ondersteuning toe te voegen alles wat je nodig hebt om bij te houden is het dia nummer. Je voegt toe aan de geschiedenislijst elke keer dat de dia verandert.

Hier is de regel code die u moet toevoegen:

history.pushState(slideNumber, null, null);

u zult merken dat deze code de paginatitel niet verandert met het tweede argument (omdat het toch niet werkt) en de URL niet wijzigt (u zult zien hoe dat te doen in een moment). Het enige wat het doet is het slidenummer opslaan.

voor de volledige afbeelding zijn hier de twee aanroepen naar history.pushState() op hun juiste plaats – de event handlers voor de volgende en vorige links:

terugkeren naar een vorige pagina

wanneer u de pushState() methode gebruikt, moet u ook nadenken over de natuurlijke tegenhanger, de onPopState gebeurtenis. Terwijl de methode pushState() een nieuw item in de geschiedenislijst van de browser plaatst, geeft de gebeurtenis onPopState u de kans om ermee om te gaan wanneer de gebruiker terugkeert.

om te begrijpen hoe dit werkt, overweeg wat er gebeurt als een bezoeker door alle dia ‘ s in het Dictionnaire Infernal voorbeeld stapt. Als elke nieuwe dia wordt geladen, de pagina voegt een geschiedenis ingang. Maar als de gebruiker een stap terug doet met de Back-knop, gebeurt er niets.

om deze tekortkoming op te lossen, moet u de gebeurtenis onPopState afhandelen, die na elke geschiedenisnavigatie wordt geactiveerd. (Dit geldt ook als u een van de geschiedenismethoden gebruikt, zoals history.back(), evenals wanneer de gebruiker op de navigatieknoppen van de browser klikt.)

de gebeurtenis onPopState geeft uw code de statusinformatie die u eerder hebt opgeslagen met pushState(). In dit geval is dat slechts het slidenummer, dat u kunt pakken van de eigenschap state van het gebeurtenisargument, zoals zo:

var slideNumber = e.State;

Het is uw taak om de statusinformatie te gebruiken om de juiste versie van de pagina te herstellen. In het huidige voorbeeld betekent dat het laden van de bijbehorende slide door de handige goToSlide() functie aan te roepen die alle slide navigatie afhandelt. De volledige code is kort en eenvoudig:

merk op dat u moet controleren of e.State is null, wat gebeurt op sommige browsers wanneer de pagina voor het eerst wordt geladen en er geen status wordt opgeslagen.

de URL wijzigen

de huidige versie van dit voorbeeld ondersteunt de geschiedenislijst, maar speelt niet goed met de Herlaadknop. Als u bijvoorbeeld doorklikt naar de derde dia en vervolgens de pagina ververst, komt u terug aan het begin. Je zult jezelf in dezelfde situatie bevinden als je probeert om een van de dia ‘ s bladwijzer te maken — Keer terug naar de bladwijzer en je begint weer op de eerste dia.

de oplossing voor deze problemen is om de History API te gebruiken om de URL te wijzigen. Maar er is een belangrijke reden dat ik deze stap tot de laatste heb gelaten. Vaak veranderen voorbeelden die de History API gebruiken de URL, maar gebruiken ze de nieuwe URL niet. Dit kan leiden tot een web-app die breekt wanneer de gebruiker het ververst (met een lelijke 404-fout), of gaat naar een soortgelijke maar iets andere versie van de pagina. Als u niet zeker weet hoe om te gaan met verschillende URL ‘ s, er is geen schande in het gebruik van de vereenvoudigde aanpak van het vorige voorbeeld.

dus laten we zeggen dat je klaar bent om in te duiken, betere URL ‘ s te maken, en mooi te spelen met bladwijzers en browservernieuwingen. Er zijn twee basisbenaderingen die u kunt volgen:

  • Wijzig de URL-paginanaam helemaal. In het Dictionnaire Infernal voorbeeld kun je de URL wijzigen in Slide1.html, Slide2.html, enzovoort als de gebruiker door de dia ‘ s beweegt. De adder is dat je ofwel echte pagina ‘ s met deze namen moet hebben (doe dat niet, het is omslachtig), of je moet routing instellen zodat wanneer je webserver een verzoek voor Slide2 krijgt.html het draait code die de juiste versie van de pagina maakt.
  • behoud dezelfde paginanaam maar voeg informatie toe aan de query-string. Dit is een eenvoudigere, kleinere aanpak. Als de gebruiker door de slideshow reist, eindig je met URL ‘ s zoals SlideShow.html?slide = 1, dan SlideShow.html?dia = 2, diavoorstelling.html?slide = 3, enzovoort. Het voordeel van deze aanpak is dat het trivially gemakkelijk om een klein stukje JavaScript dat de query string controleert en zorgt ervoor dat je op de juiste dia wanneer de pagina wordt herladen schrijven. Je hebt geen servercode nodig om dit te laten werken-één pagina kan het allemaal.

Hier is een gewijzigde versie van de pushState() aanroep die u eerder zag en die de tweede benadering gebruikt. Deze code stopt het slidenummer op het einde van de URL:

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

en hier is de code die wordt uitgevoerd wanneer de pagina opnieuw wordt geladen. Het controleert op de dia informatie in de URL, en — als het een juist nummer vindt-roept de goToSlide() functie op om de dia te laden.

nu zult u nooit uw plaats verliezen in de diavoorstelling. U kunt de volledige versie van dit voorbeeld uitproberen of hier alles downloaden.

Final details

De History API is eenvoudig te gebruiken, maar het maakt het ook gemakkelijk om grotere problemen te creëren die je oplost. Nu je weet hoe alles in elkaar past, hier zijn een aantal laatste stukjes advies:

  • Als u pusht, moet u pop. DepushState() methode enonPopState gebeurtenis zijn partners. Wat je in de ene stopt, krijg je terug bij de andere.
  • wijzig de URL niet tenzij u klaar bent om het af te handelen. Het is leuk om uw URL te wijzigen om uw veranderende pagina weer te geven, maar u moet in staat zijn om verzoeken voor elke URL die u gebruikt te behandelen. Als uw URL wijst naar een pagina die niet bestaat, uw toepassing zal breken op Vernieuwen en bladwijzers.
  • gebruik een aangepast statusobject om meer informatie op te slaan. Je hoeft het niet bij een simpel getal te houden. U kunt een volledig aangepast object in staat, die alle informatie die u nodig hebt voor een complexe taak kan bundelen.



Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.