En Enkel Introduksjon Til Historie API I JavaScript
Historie API Er en Av De JavaScript teknikker som hver webutvikler trenger å vite kaldt. Uten det, vil et enkelt klikk På Tilbake-knappen hoppe rett ut av søknaden din. Du vil miste noen pågående arbeid, og brukeren vil bli tvunget til å starte helt på nytt.
Heldigvis er det en enkel løsning. Helt siden formaliseringen AV HTML5 (og Utgivelsen Av Internet Explorer 10), har vi hatt En Historie API som lar deg legge til historikklisten og reagere på frem og tilbake navigasjon. I denne artikkelen lærer du hvordan det fungerer — og du vil prøve det med et levende eksempel.
Men før vi går videre, la oss se nærmere på problemet.
I gamle dager på nettet gjorde en nettside en ting-vise ting. Når du ønsket å se på noe annet, klikket du på en lenke og gikk til en NY URL.
Som JavaScript vokste kraftigere, utviklere innså at hver nettside kan være et komplett program i seg selv. En nettside kan rival en desktop applikasjon! Problemet var At Knappene Tilbake Og Fremover i nettleseren ikke passet denne nye applikasjonsmodellen. En bruker kan for eksempel utføre en rekke oppgaver i et webprogram på en enkelt side, og deretter forvente å bruke Tilbake-knappen for å gå tilbake et enkelt trinn. I stedet Vil Tilbakeknappen gå tilbake til forrige nettside, og effektivt slå Av JavaScript-appen midt i hva den gjorde.
ofte var denne oppførselen ikke intuitiv. Vurder for eksempel et program som brukerXMLHttpRequest
– objektet til å hente nye data og oppdatere siden. For brukeren kan det se ut som om de reiser til en ny side. Men hvis de gjør feilen ved å bruke Tilbakeknappen, blir illusjonen knust og alt går sidelengs.
la oss ta en nærmere titt. Her er et eksempel som lar deg gå gjennom Dictionnaire Infernal, en berømt (og nå offentlig domene) bok fra 1818 som beskriver merkelige dyr fra overtro og mytologi. Trikset er At Forrige og Neste koblinger ikke tar deg til en annen side. I stedet utløser de et asynkront kall gjennom XMLHttpRequest
som får informasjonen for neste lysbilde. Deretter Oppdaterer JavaScript-koden lysbildeboksen uten å forstyrre innholdet på resten av siden.
her er en live-versjon av eksemplet, komplett Med Historie API-støtte. Selv om alt foregår i en enkelt nettside, kan du bruke Frem og Tilbake-knappene for å sømløst gå fra ett bilde til det neste. Du kan til Og Med bruke Reload-knappen (laster inn gjeldende lysbilde, i stedet for å starte hele appen på nytt), og du kan plassere bokmerker som holder gjeldende tilstand — med andre ord fører de deg rett tilbake til lysbildet du ser på.
og her er en gammel versjon av eksemplet som ikke bruker Historikk-API. Det spiller ingen rolle hvor langt du er i sidevisningen – når Du bruker Tilbakeknappen, hopper du tilbake til forrige nettside. Forward og Reload knappene er på samme måte brutt. Bokmerker start appen på nytt fra begynnelsen.
du kan laste ned all kildekoden her for å spille med. (Det fungerer imidlertid ikke lokalt, fordi det brukerXMLHttpRequest
– objektet til å gjøre webforespørsler.) I resten av denne artikkelen vil jeg bryte ned hvordan alt fungerer.
Forbereder eksemplet
Før Vi kommer inn I Historie API, er det viktig å ha en grunnleggende forståelse av hvordan dette eksemplet fungerer. Det er alt ganske enkelt.
siden bruker et tall for å holde oversikt over lysbildet som vises for øyeblikket. Når du klikker Neste eller Forrige, endrer koden gjeldende lysbildenummer. Deretter bruker den sin egen goToSlide()
funksjon for å oppdatere siden.
goToSlide()
funksjonen er der det virkelige arbeidet finner sted. Det starter en asychronous forespørsel ved hjelp av infamous XMLHttpRequest
objekt.
det er opp til deg å bestemme hvordan lysbildeinnholdet genereres og sendes tilbake til anropskoden på siden. Vanligvis har du en slags rutingsramme som utløser riktig server – side kode. Den server – side koden kan da ta tak i lysbildeinnholdet fra en cache, en database, en fil eller til og med en hardkodet blokk med markering.
i dette eksemplet har jeg holdt ting så enkelt som mulig. Forespørselen griper HTML-markeringen fra en statisk fil. Så hvis du ber om det tredje lysbildet (med en relativ URL som Lysbilder/3), får du EN utdrag AV HTML-markering for bare det lysbildet. Rolig!
når forespørselen er ferdig, utløser nettleserennewSlideReceived()
hendelsesbehandling. Da er det bare et spørsmål om å ta den mottatte markeringen og sette den inn på siden, ved hjelp av en plassholder <div>
.
Det er alt du trenger å vite for å bygge den naive versjonen av denne siden, som ikke støtter nettleserhistorikk.
historikkobjektet
history
objektet har eksistert nesten siden Begynnelsen Av JavaScript. Men for mye av livet var det langt mindre kraftig (og langt mindre nyttig) enn det er i dag.
den opprinnelige history
objektet har bare en egenskap og tre grunnleggende metoder. Egenskapen er length
, og den forteller deg hvor mange oppføringer som er i nettleserens historikkliste:
alert("You have " + history.length + " pages in the history.");
denne detalj er for det meste ubrukelig.
de tre opprinnelige history
metoder er back()
(sender en besøkende ett skritt tilbake i nettleserloggen), forward()
(sender en besøkende ett skritt fremover) og go()
(tar en numerisk forskyvning som forteller leseren hvor mange trinn som skal gå fremover eller bakover). Alt dette legger opp til relativt lite, med mindre du ønsker å designe dine egne tilbake og frem knapper på en nettside.
HistoryAPI legger til to mye mer nyttige ingredienser:pushState()
metoden ogonPopState
hendelsen.
Legge til en oppføring i historikklisten
pushState()
– metoden er midtpunktet i Historikk-API-EN. Den lar deg legge til et nytt element i historikklisten for gjeldende side. Her er hvordan det ser ut:
på dette punktet lurer du kanskje på — hva er poenget med å ha mer enn en oppføring for samme side? Trikset er at hver oppføring har noen stat knyttet til det – et koblet stykke informasjon eller objekt som du angir. Når brukeren går tilbake gjennom historikklisten, får du den tilsvarende tilstandsinformasjonen, slik at du kan returnere siden til den forrige versjonen.
pushState()
– metoden tar tre argumenter:
- Data. Det første argumentet er alle data du vil lagre for å representere gjeldende tilstand på denne siden. Du bruker denne informasjonen til å gjenopprette siden når brukeren går tilbake gjennom logglisten.
- Tittel. Det andre argumentet er sidetittelen du vil at nettleseren skal vise. For tiden er alle nettlesere forenet i å ignorere denne detalj. (Så du kan bare passere
null
.) - URL. Det tredje argumentet er den nye versjonen AV NETTADRESSEN du vil vise for siden i nettleserens adressefelt. Dette lar deg legge til bedre støtte For Reload-knappen og nettleserbokmerkene.
I Dictionnaire Infernal slideshow eksempel, er det enkelt å legge historie støtte Alt du trenger å holde styr på er lysbildenummeret. Du legger til i logglisten hver gang lysbildet endres.
her er kodelinjen du må legge til:
history.pushState(slideNumber, null, null);
du vil legge merke til at denne koden ikke endrer sidetittelen med det andre argumentet (fordi det ikke fungerer uansett) og endrer IKKE NETTADRESSEN (du ser hvordan du gjør det om et øyeblikk). Alt den gjør er å lagre lysbildenummeret.
for hele bildet, her er de to anropene til history.pushState()
på riktig sted — hendelsesbehandlerne For Neste og Forrige lenker:
Tilbake til forrige side
når du bruker pushState()
metoden, må du også tenke på dens naturlige motstykke, onPopState
hendelsen. Mens pushState()
– metoden setter en ny oppføring i nettleserens historikkliste, gironPopState
– hendelsen deg muligheten til å håndtere det når brukeren kommer tilbake.
for å forstå hvordan dette fungerer, bør du vurdere hva som skjer hvis en besøkende går gjennom alle lysbildene i Dictionnaire Infernal-eksemplet. Når hvert nytt lysbilde er lastet opp, legger siden til en loggoppføring. Men hvis brukeren går tilbake med Tilbakeknappen, skjer ingenting.
for å fikse denne mangelen må du håndtere onPopState
– hendelsen, som utløses etter hver historikknavigasjon. (Dette inkluderer hvis du bruker en av historikkmetodene, som history.back()
, samt når brukeren klikker på navigasjonsknappene i nettleseren.)
onPopState
hendelsen gir koden din med tilstandsinformasjonen du lagret tidligere med pushState()
. I dette tilfellet er det bare lysbildenummeret, som du kan hente frastate
egenskapen til hendelsesargumentet, slik som:
var slideNumber = e.State;
din jobb er å bruke tilstandsinformasjonen til å gjenopprette riktig versjon av siden. I det nåværende eksemplet betyr det å laste inn det tilsvarende lysbildet ved å ringe den praktiskegoToSlide()
– funksjonen som håndterer all lysbildenavigering. Den komplette koden er kort og grei:
Legg merke til at du må sjekke om e.State
er null
, som skjer i noen nettlesere når siden lastes for første gang, og det er ingen tilstand lagret.
Endre URL
den nåværende versjonen av dette eksemplet støtter historikklisten, men spiller ikke pent med Reload-knappen. Hvis du for eksempel klikker gjennom til det tredje lysbildet og deretter oppdaterer siden, vil du ende opp igjen i begynnelsen. Du vil finne deg selv i samme situasjon hvis du prøver å bokmerke et av lysbildene — gå tilbake til bokmerket, og du vil starte tilbake på det første lysbildet.
løsningen på disse problemene er å bruke Historie API for å endre URL. Men det er en viktig grunn til at jeg har forlatt dette trinnet til sist. Ofte, eksempler som bruker Historie API endre URL, men ikke bruke den nye URL. Dette kan føre til en webapp som bryter når brukeren oppdaterer den (med en stygg 404-feil), eller går til en lignende, men litt annen versjon av siden. Hvis du ikke er sikker på hvordan du håndterer Forskjellige Nettadresser, er det ingen skam å bruke den forenklede tilnærmingen fra forrige eksempel.Så la oss si at du er klar til å dykke inn, lage bedre Nettadresser, og spill pent med bokmerker og nettleseroppdateringer. Det er to grunnleggende tilnærminger du kan ta:
- Endre URL-sidenavnet helt. I Dictionnaire Infernal-eksemplet kan DU endre NETTADRESSEN Til Slide1.html, Slide2.html, og så videre som brukeren beveger seg gjennom lysbildene. Fangsten er at du må enten ha faktiske sider med disse navnene (ikke gjør det, det er tungvint), eller du må sette opp ruting slik at når webserveren din får en forespørsel Om Slide2.html det kjører kode som skaper den riktige versjonen av siden.
- Behold det samme sidenavnet, men legg til informasjon i spørringsstrengen. Dette er en enklere, mindre skala tilnærming. Når brukeren reiser gjennom lysbildeserien, vil du ende Opp Med Nettadresser som Lysbildeserie.html?slide=1, Deretter SlideShow.html?slide=2, SlideShow.html?slide = 3, og så videre. Fordelen med denne tilnærmingen er at det er trivielt enkelt å skrive Et Lite Stykke JavaScript som sjekker spørringsstrengen og sørger for at du er på høyre lysbilde når siden lastes på nytt. Du trenger ingen serverkode for å gjøre dette arbeidet — en side kan gjøre alt.
her er en modifisert versjon avpushState()
samtale du så tidligere som bruker den andre tilnærmingen. Denne koden fyller lysbildenummeret på slutten av NETTADRESSEN:
history.pushState(slide, null, "Dictionnaire.html?slide=" + slide);
Og her er koden som kjører når siden lastes på nytt. Den sjekker for lysbildeinformasjonen I NETTADRESSEN — og — hvis den finner et riktig nummer-kallergoToSlide()
– funksjonen for å laste opp lysbildet.
nå vil du aldri miste din plass i lysbildeserien. Du kan prøve ut den komplette versjonen av dette eksemplet eller laste ned alt her.
Final details
Historikk API er enkel å bruke, men det gjør det også enkelt å lage større problemer som du løser. Nå som du vet hvordan alt passer sammen, her er noen siste biter av råd:
- hvis du trykker, må du pop.
pushState()
– metoden ogonPopState
– hendelsen er partnere. Hva du putter i med en, du komme tilbake med den andre. - ikke endre URL-ADRESSEN med mindre du er klar til å håndtere DEN. Det er fint å endre NETTADRESSEN din for å gjenspeile siden du endrer, men du må kunne håndtere forespørsler for HVER NETTADRESSE du bruker. HVIS NETTADRESSEN peker til en side som ikke finnes, vil programmet bryte på oppdateringer og bokmerker.
- Bruk et egendefinert tilstandsobjekt til å lagre mer informasjon. Du trenger ikke å holde fast med et enkelt nummer. Du kan sette et helt egendefinert objekt i tilstand, som kan pakke sammen all informasjonen du trenger for en kompleks oppgave.