Kako postaviti pametne telefone i računala. Informativni portal

Js povijest preglednika. Uvod u HTML5 History API

Ako nikada prije niste vidjeli povijesni predmet, ne brinite. Do sada nam nije mogao ponuditi ništa korisno. U stvarnosti, tradicionalni povijesni objekt ima samo jedno svojstvo i tri glavne metode. Ova nekretnina duljina- sadrži informacije o broju stavki na popisu povijesti pregledavanja (tj. popisu nedavno posjećenih web stranica koji održava preglednik). Evo primjera korištenja ovog svojstva:

Alert("Spremili ste " + history.length + " stranice u svojoj povijesti preglednika.");

Povijest.back();

Učinak ove metode jednak je kliku korisnika na gumb "Natrag" u pregledniku. Na sličan način možete koristiti metodu naprijed() pomaknuti se korak naprijed ili metoda ići() za pomicanje naprijed ili nazad određeni broj koraka.

Ali ništa od toga nema veliku vrijednost osim ako ne želite izraditi vlastite gumbe za povratak i naprijed za svoju web stranicu. Ali HTML5 ovom povijesnom objektu dodaje nekoliko dodatnih mogućnosti koje se mogu koristiti za postizanje mnogo ambicioznijih ciljeva.

Glavna među tim značajkama je metoda pushState(), koja vam omogućuje promjenu URL-a u adresnoj traci preglednika bez ažuriranja sadržaja stranice. Ova je značajka korisna u specifičnoj situaciji, naime pri izradi dinamičkih stranica koje tiho učitavaju novi sadržaj i neprimjetno se ažuriraju. U ovoj situaciji URL stranice i njezin sadržaj možda se ne podudaraju.

Na primjer, ako stranica dinamički učitava sadržaj s druge stranice, izvorni URL stranice neće se promijeniti, što može uzrokovati razne probleme s označavanjem te stranice. Ovaj se problem može riješiti praćenjem povijesti sesija.

Ako još ne vidite kako to učiniti, ne brinite, u sljedećem odjeljku pogledat ćemo stranicu koja je idealna za korištenje vaše povijesti pregledavanja.

16 odgovora

Kratak odgovor je: ne možete.

Tehnički, postoji točan način provjere autentičnosti:

Povijest.prethodni

Međutim, ovo neće uspjeti. Problem je u tome što se u većini preglednika ovo smatra kršenjem sigurnosti i obično samo vraća nedefinirano.. p>

Povijest.duljina

Ovo je nekretnina koju su drugi predložili...
Međutim, duljina ne funkcionira u potpunosti jer ne navodite gdje u priči. Također, ne počinje uvijek istim brojem. Na primjer, preglednik koji nije konfiguriran za odredišnu stranicu počinje s 0, dok drugi preglednik koji koristi odredišnu stranicu počinje s 1.

Povijest.back();

Povijest.go(-1);

i samo se očekivalo da ako se ne možete vratiti, klik na vezu neće učiniti ništa.

Moj kod omogućuje pregledniku da se vrati na jednu stranicu, a ako to ne uspije, učitava rezervni URL. Također otkriva promjene hashtagova.

Ako gumb za povratak nije dostupan, rezervni url će se učitati nakon 500 ms, tako da preglednik ima dovoljno vremena za učitavanje prethodne stranice. Učitavanje povratnog URL-a odmah nakon window.history.go(-1); uzrokovat će preglednik da koristi zamjenski url jer js skripta još nije zaustavljena.

Function historyBackWFallback(fallbackUrl) ( fallbackUrl = fallbackUrl || "/"; var prevPage = window.location.href; window.history.go(-1); setTimeout(function())( if (window.location.href == prevPage ) ( window.location.href = fallbackUrl; ) ), 500); )

ovo izgleda kao trik:

Funkcija goBackOrClose() ( window.history.back(); window.close(); //ili ako niste zainteresirani za zatvaranje prozora, učinite nešto drugo ovdje //npr. theBrowserCantGoBack(); )

Pozovite history.back(), a zatim window.close(). Ako se preglednik može vratiti u povijest, neće moći prijeći na sljedeću izjavu. Ako se ne može vratiti, zatvorit će prozor.

Međutim, imajte na umu da ako se do stranice dođe upisivanjem URL-a, firefox neće dopustiti skripti da zatvori prozor.

Ne možete izravno provjeriti je li gumb za povratak dostupan. Možete pogledati history.length>0, ali to će biti točno samo ako su stranice ispred i na trenutnoj stranici. Možete biti sigurni da je gumb za povratak neupotrebljiv samo ako history.length===0 .

Ako to nije dovoljno dobro, otprilike sve što možete učiniti je nazvati history.back() i, ako je vaša stranica još uvijek učitana, gumb Natrag je siv! Naravno, to znači da ako je gumb za povratak dostupan, jednostavno ste otišli sa stranice. Nije vam dopušteno nadjačati navigaciju u onunload, tako da sve što možete učiniti da zaustavite obrnuto je da vratite nešto iz onbeforeunload, što će uzrokovati pojavu velikog iritantnog prompta. Nije vrijedno toga.

Zapravo, obično je jako loša ideja raditi bilo što s poviješću. Navigacija poviješću je za preglednik Chrome, a ne za web stranice. Dodavanje "povratnih" poveznica obično uzrokuje više zbunjenosti korisnika nego što vrijedi.

Evo kako sam ja to napravio.

Upotrijebio sam događaj "beforeunload" za postavljanje Booleove vrijednosti. Zatim sam postavio vremensko ograničenje da vidim hoće li "beforeunload" početi raditi.

Var $window = $(window), $trigger = $(".select_your_link"), rezervni = "your_fallback_url"; hasHistory = false; $window.on("beforeunload", function())( hasHistory = true; )); $trigger.on("click", function())( window.history.go(-1); setTimeout(function())( if (!hasHistory)( window.location.href = backback; ) ), 200) ; vrati netočno; ));

Čini se da radi u glavnim preglednicima (do sada testirano FF, Chrome, IE11).

U mojim projektima postoji isječak:

Funkcija back(url) ( if (history.length > 2) ( // ako povijest nije prazna, idite natrag: window.History.back(); ) else if (url) ( // idite na navedeni rezervni url: window .History.replaceState(null, null, url); ) else ( // idi kući: window.History.replaceState(null, null, "/"); ) )

FYI: Koristim History.js za upravljanje poviješću preglednika.

Zašto uspoređivati ​​history.length s brojem 2?

Jer počevši Chrome stranica smatra se prvim elementom u povijesti preglednika.

Postoji nekoliko mogućnosti za history.length i ponašanje korisnika:

  • Korisnik otvara novu praznu karticu preglednika i zatim pokreće stranicu. history.length = 2 i želimo onemogućiti back() u ovom slučaju jer će korisnik otići na praznu karticu.
  • Korisnik otvara stranicu u novoj kartici klikom na poveznicu negdje prije. history.length = 1 i opet želimo onemogućiti back() metodu.
  • I konačno korisnik dolazi do trenutne stranice nakon višestrukog ponovnog učitavanja stranice. history.length > 2 i sada se može omogućiti back().

Napomena: nedostaje mi slučaj kada korisnik dođe na trenutnu stranicu nakon klika na vezu s vanjske stranice bez target="_blank" .

Napomena 2: document.referrer je prazan kada otvorite web mjesto unosom njegove adrese, a također i kada web mjesto koristi ajax za učitavanje podstranica, tako da sam prestao provjeravati ovu vrijednost u prvom slučaju.

history.length je beskoristan jer ne pokazuje može li se korisnik vratiti u povijest. Također različiti preglednici koriste početne vrijednosti 0 ili 1 - ovisi o pregledniku.

Radno rješenje je korištenje događaja $(window).on("beforeunload", ali nisam siguran da će funkcionirati ako se stranica učita putem ajaxa i koristi pushState za promjenu povijesti prozora.

Pa sam upotrijebio sljedeće rješenje:

Var currentUrl = window.location.href; prozor.povijest.natrag(); setTimeout(function())( // ako lokacija nije promijenjena u 100 ms, tada nema povratne povijesti if(currentUrl === window.location.href)( // preusmjeravanje na korijen stranice window.location.href = " / "; ) ), 100);

Budite oprezni s window.history.length jer također sadrži unose za window.history.forward()

Dakle, možete imati window.history.length s više od 1 unosa, ali bez unosa povijesti. To znači da se ništa neće dogoditi ako pokrenete window.history.back()

Došao sam do sljedećeg pristupa. Koristi događaj onbeforeunload kako bi odredio napušta li preglednik stranicu ili ne. Ako u određenom vremenskom razdoblju ne bude preusmjeren na sigurnosnu kopiju.

Var goBack = funkcija goBack(fallback)( var useFallback = true; window.addEventListener("beforeunload", function())( useFallback = false; )); window.history.back(); setTimeout(function())( if (useFallback)( window.location.href = backback; ) ), 100); )

Ovu funkciju možete pozvati pomoću goBack("fallback.example.org") .

window.location.pathname će vam dati trenutni URI. Na primjer, https://domain/question/1234/i-have-a-problem vratit će /question/1234/i-have-a-problem . Pogledajte dokumentaciju o window.location

Tada će nam poziv split() dati sve fragmente tog URI-ja. pa ako uzmemo naš prethodni URI, imat ćemo nešto poput ["", "pitanje", "1234", "imam-problem"] . Pogledajte dokumentaciju o String.prototype.split() za dodatne informacije.

Poziv filter() ovdje služi za filtriranje praznog niza stvorenog obrnutom kosom crtom. Vratit će samo URI fragment čija je duljina veća od 1 (niz koji nije prazan). Tako bismo imali nešto poput ["pitanje", "1234", "imam-pitanje"] . Moglo bi se napisati ovako:

"koristi strog"; window.location.pathname.split("/").filter(function(fragment) ( return fragment.length > 0; ));

Više informacija potražite u dokumentaciji o Array.prototype.filter() i svrsi destrukturiranja.

Sada, ako se korisnik pokuša vratiti dok je na https://domain/, nećemo pokrenuti naredbu if i stoga nećemo pozvati metodu window.history.back() kako bismo zadržali korisnika na našoj web stranici. Ovaj URL će biti ekvivalentan onom koji ima duljinu 0, a 0 > 0 je netočan. Posljedično, ne uspijeva tiho. Naravno, možete registrirati nešto ili izvršiti neku drugu radnju ako želite.

"koristi strog"; funkcija prethodnaStranica() ( if (window.location.pathname.split("/").filter((( length )) => length > 0).length > 0) ( window.history.back(); ) else ( upozorenje("Ne možete se više vratiti unatrag..."); ) )

Ograničenja

Naravno, ovo rješenje neće raditi ako preglednik ne podržava History API. Provjerite dokumentaciju kako biste saznali više o tome prije korištenja ovog rješenja.

Prije HTML5 jedina stvar koju nismo mogli kontrolirati i kojom nismo mogli upravljati (bez ponovnog učitavanja sadržaja ili hakiranja location.hash) bila je povijest jedne kartice. Dolaskom HTML5 history API-ja sve se promijenilo - sada možemo hodati kroz povijest (mogli smo to i prije), dodavati elemente u povijest, reagirati na prijelaze u povijesti i druge korisne stvari. U ovom ćemo članku pogledati HTML5 History API i napisati jednostavan primjer za ilustraciju njegovih mogućnosti.

Osnovni koncepti i sintaksa History API oslanja se na jedno DOM sučelje - objekt History. Svaka kartica ima jedinstveni objekt Povijest, koji se nalazi u window.history. Povijest ima nekoliko metoda, događaja i svojstava kojima možemo upravljati iz JavaScripta. Svaka stranica kartice (objekt dokumenta) je objekt zbirke povijesti. Svaki element priče sastoji se od URL-a i/ili objekta stanja i može imati naslov, objekt dokumenta, podatke obrasca, poziciju pomicanja i druge informacije povezane sa stranicom.

Glavne metode objekta History:

  • window.history.length: Broj zapisa u trenutnoj sesiji povijesti
  • window.history.state: Vraća trenutni objekt povijesti
  • window.history.go(n) : Metoda za šetnju kroz povijest. Pomak u odnosu na trenutnu poziciju prosljeđuje se kao argument. Ako se proslijedi 0, ažurirat će se Trenutna stranica. Ako indeks ide dalje od povijesti, onda se ništa neće dogoditi.
  • window.history.back() : Metoda identična pozivu go(-1)
  • window.history.forward() : Metoda identična go(1)
  • window.history.pushState(data, title [, url]) : Dodaje element povijesti.
  • window.history.replaceState(data, title [, url]) : Osvježava trenutnu stavku povijesti
  • Za povratak 2 koraka unatrag u povijesti možete koristiti:
    povijest.go(-2)
    Za dodavanje elemenata povijesti možemo koristiti history.pushState:
    history.pushState((foo: "bar"), "Naslov", "/baz.html")
    Za promjenu unosa povijesti možemo koristiti history.replaceState:
    history.replaceState((foo: "bat"), "New Title") Primjer uživo Sada znamo osnove, pogledajmo primjer uživo. Napravit ćemo web upravitelj datoteka koji će vam omogućiti da pronađete URI odabrane slike(). Upravitelj datoteka koristi jednostavan struktura datoteke, napisano u JavaScriptu. Kada odaberete datoteku ili mapu, slika se dinamički ažurira.

    Koristimo data-* atribute za pohranu naslova svake slike i koristimo svojstvo skupa podataka da dobijemo to svojstvo:

  • račić2.png

  • Kako bi sve radilo brzo, učitavamo sve slike i dinamički ažuriramo atribut src. Ovo ubrzanje stvara jedan problem - lomi gumb za povratak, pa se ne možete kretati naprijed ili natrag kroz slike.

    Povijest HTML5 dolazi u pomoć! Svaki put kada odaberemo datoteku, kreira se novi unos u povijest i ažurira se lokacija dokumenta (sadrži jedinstveni URL slike). To znači da se pomoću gumba za povratak možemo kretati kroz naše slike, dok ćemo u adresnoj traci imati izravnu poveznicu na sliku koju možemo označiti ili poslati nekome.

    Šifra Imamo 2 dive. Jedan sadrži strukturu mape, drugi sadrži trenutnu sliku. Cijela aplikacija se kontrolira pomoću JavaScripta. Obuhvaćat će se samo najvažnije točke. Primjer izvornog koda je vrlo kratak (oko 80 redaka), pogledajte ga nakon što pročitate cijeli članak.

    Metoda bindEvents pridružuje rukovatelje popstate događaju, koji se poziva kada se korisnik kreće kroz povijest i omogućuje aplikaciji da ažurira svoje stanje.
    window.addEventListener("popstate", function(e)( self.loadImage(e.state.path, e.state.note); ), false);
    Objekt događaja koji se prosljeđuje rukovatelju događaja popstate ima svojstvo stanja - to su podaci koje smo proslijedili kao prvi argument za pushState ili replaceState.

    Obrađivač događaja klika prilažemo divu koji predstavlja strukturu naše datoteke. Korištenjem delegiranja događaja otvaramo ili zatvaramo mapu ili učitavamo sliku (s unosom dodanim u povijest). Gledamo className nadređenog elementa kako bismo razumjeli na koji element smo kliknuli:
    - Ako je ovo mapa, otvaramo je ili zatvaramo
    - Ako je slika, onda je pokažemo i dodamo element priče

    Dir.addEventListener("click", function(e)( e.preventDefault(); var f = e.target; // Ovo je mapa if (f.parentNode.classList.contains("folder")) ( // Otvorite ili zatvorite mapu self.toggleFolders(f); ) // Ovo je slika else if (f.parentNode.classList.contains("photo"))( note = f.dataset ? f.dataset.note: f. getAttribute("data- note"); // nacrtajte sliku self.loadImage(f.textContent, note); // dodajte element povijesti history.pushState((note: note, path:f.textContent), "", f.textContent); ) ) , false);
    Metoda koja mijenja sadržaj slike i ažurira njezin opis vrlo je jednostavna:
    loadImage: funkcija(put, bilješka)( img.src = put; h2.textContent = bilješka; )
    Dobili smo jednostavnu aplikaciju koja pokazuje mogućnosti ažurirano sučelje Povijesni objekt. Koristimo pushState za dodavanje elementa povijesti i popstate događaj za ažuriranje sadržaja stranice. Osim toga, kada kliknemo na sliku, u adresnoj traci dobivamo njezinu stvarnu adresu koju možemo spremiti ili poslati nekome.

    Kada se može koristiti? Firefox 4+
    Safari 5+
    Chrome 10+
    Opera 11.5+
    iOS Safari 4.2+
    Android 2.2+
    IE???
    Popis preglednika koji podržavaju API povijesti

    Sve donedavno, mi programeri nismo mogli puno učiniti sa stanjem i poviješću preglednika. Mogli bismo provjeriti broj stavki u povijesti i gurati korisnike naprijed i natrag, ali to korisniku donosi malo koristi. S porastom dinamičnijih web stranica, trebamo više kontrole. Srećom, HTML5 nam daje tu kontrolu proširenjem JavaScript History API-ja.

    Koja je svrha?

    Podrazumijeva se da su URL-ovi važni. oni su the način pristupa golemim zbirkama informacija i resursa na webu, a nedavno su počeli predstavljati predviđeno stanje web aplikacije. Možete kopirati ove URL-ove i podijeliti ih sa svojim prijateljima ili ih koristiti za stvaranje veza iz bilo kojeg HTML dokumenta. One su vene mreže, i treba se brinuti o vama.

    Prethodno je JavaScript History API nudio neke vrlo jednostavne funkcije:

    // Provjerite duljinu hrpe povijesti console.log(history.length); // Pošaljite korisnički agent naprijed console.log(history.forward()); // Pošalji korisničkom agentu natrag console.log(history.back()); // Šalji korisničkog agenta natrag (negativno) ili naprijed (pozitivno) // za zadani broj stavki console.log(history.go(-3));

    S dinamičkim Ajax web aplikacijama, gdje se preglednik ažurira stranica u dijelovima umjesto potpune promjene lokacije, teško je dati korisniku URL za označavanje ili dijeljenje trenutnog stanja aplikacije. Identifikatori fragmenata, poput onih koji se koriste u naslovima ovog članka putem atributa id, pružaju neke informacije o stanju, ali u potpunosti ovise o skriptama na strani klijenta.

    Spremite ovu datoteku i otvorite je u svom omiljenom editoru. Mora mu se pristupiti putem HTTP-a, što znači da trebate ili lokalni poslužitelj (npr. http://localhost/) ili online web poslužitelj na koji možete učitati. Izravno gledanje datoteke pomoću funkcije Open File vašeg preglednika neće raditi jer koristi file:// protokol, a ne HTTP. Također svakako ažurirajte atribute href na svakoj od navigacijskih veza kako biste osigurali ispravnu strukturu direktorija. Osobno gledam demo lokalno na http://localhost/history.

    Radit ćemo isključivo unutar elementa na kraju . Kôd uključuje neke jednostavne stilove i dinamički mijenja sadržaj dok kliknete na veze. U stvarnosti, ovo se može učitati s vašeg poslužitelja putem XMLHttpRequesta, ali za potrebe ove demonstracije ja sam to spojio u samostalnu datoteku. Važan dio je da imamo brzu i prljavu dinamičnu stranicu za rad, pa neka zabava počne!

    Trenutačno ne postoji URL koji se može označiti za različita stanja ove stranice. Ako kliknete oko navigacijskih stavki, a zatim kliknete Natrag u svom pregledniku, nećete biti vraćeni u prethodno stanje i čak možete biti odvedeni sa stranice na ono što ste prije gledali (ovisno o vašem pregledniku). Bilo bi lijepo kada biste mogli podijeliti "Čarape" sa svojim prijateljima, zar ne? To možemo učiniti putem history.pushState() .

    Metoda history.pushState() uzima tri parametra:

    Podaci Neki strukturirani podaci, kao što su postavke ili sadržaj, dodijeljeni povijesnoj stavci. title Naziv stavke u padajućem izborniku povijesti prikazanom gumbima preglednika za povratak i naprijed. (Napomena: ovo trenutno ne podržava nijedan veći preglednik.) url (neobavezno) URL do ovog stanja koji bi trebao biti prikazan u adresnoj traci.

    Pomoću ovih parametara možete definirati stanje stranice, tom stanju dati naziv, pa čak i dati adresu koja se može označavati, kao da se stranica potpuno ponovno učitala. Zaronimo odmah i dodamo ovo funkciji clickHandler, odmah iznad povratne izjave:

    Funkcija clickHandler(e) ( /* Snip... */ // Dodavanje stavke u zapisnik povijesti history.pushState(data, event.target.textContent, event.target.href); return event.preventDefault(); )

    Jedna linija koda koju smo dodali obavještava povijesni objekt da:

    • želimo dodati stavku u dnevnik,
    • trebao bi zapamtiti podatke koje smo već učitali,
    • trebao bi dodijeliti naziv ovom stanju na temelju teksta poveznice koju smo kliknuli (iako se to ne koristi - dobro je steći naviku bilježiti naziv za stanje), i
    • trebao bi ažurirati adresnu traku atributom href te veze.

    Ponovno učitajte stranicu u pregledniku i kliknite na nekoliko poveznica, pazeći na adresnu traku. Primijetite kako se mijenja svakim klikom, unatoč činjenici da zapravo ne odlazite s ove stranice. Ako također pogledate svoj dnevnik povijesti, vidjet ćete dugačak popis naslova stranica (u ovom slučaju "Mačići!" uvijek iznova). Pod uvjetom da je vaš poslužitelj postavljen da posluži ispravnu stranicu nakon pristupa, korisnik bi mogao kopirati taj URL i zalijepiti ga u novi prozor preglednika kako bi skočio ravno na tog mačića.

    U ovom trenutku, klikom na gumb za povratak otvorit će vam se prozor kroz stavke povijesti, ali stranica neće reagirati na ove promjene. To je zato što smo do sada stvarali samo povijesne zapise. Kako možemo dopustiti aktivnim korisnicima da se vrate u prethodno stanje? Slušamo popstate event.

    Povijesni događaji u navigaciji

    Korisnički agent aktivira popstate događaj kada korisnik navigira kroz svoju povijest, bilo unatrag ili naprijed, pod uvjetom da ne odvodi korisnika s trenutne stranice. To jest, svi oni pushState koje smo pozvali zadržat će korisnika na trenutnoj stranici, tako da će se popstate događaj pokrenuti za svaku stavku povijesti kroz koju iskoči.

    Prije završne oznake dodajte novog slušatelja za popstate događaj:

    // Vraćanje na prethodno spremljeno stanje window.addEventListener("popstate", function(event) ( console.log("popstate fired!"); updateContent(event.state); ));

    Priključujemo slušatelja događaja prozoru koji je odgovoran za aktiviranje događaja i prosljeđujemo ovaj događaj našem rukovatelju. Bilježimo poruku (tako da možemo vidjeti kada se ovaj događaj pokreće), a zatim ažuriramo sadržaj koristeći stanje koje smo prethodno spremili. Država je pridružena objektu događaja putem imovine države.

    Otvorite novu stranicu u svom pregledniku, klikajte kao prije, a zatim kliknite natrag. Kao i prije, URL u adresnoj traci mijenja se dok kružite kroz stanja, ali sada je i sadržaj vraćen na ono što bi trebao biti. Kliknite naprijed i sadržaj će se također ispravno vratiti.

    Ako pogledate konzolu za razvojne programere u Chromeu kada prvi put učitate stranicu, vidjet ćete da se popstate događaj pokreće odmah, prije nego što ste uopće kliknuli vezu. To je zato što Chrome početno učitavanje stranice smatra promjenom stanja i stoga pokreće događaj. U ovom slučaju, svojstvo stanja je null, ali na svu sreću funkcija updateContent se bavi time. Imajte to na umu kada razvijate jer bi vas moglo zateći, pogotovo ako drugi preglednici preuzmu ovakvo ponašanje.

    Prepisivanje povijesti

    Nažalost, koliko god HTML5 bio fantastičan, ne dopušta nam stvarno putovanje kroz vrijeme. Da jest, vratio bih se u djetinjstvo i rekao mlađoj sebi: "Da, trebao bi pojesti komad torte." Uzmi to kako hoćeš.

    Povijest API nam, međutim, dopušta da ispravimo stavke našeg dnevnika povijesti. Na primjer, mogli bismo ažurirati trenutno stanje kao odgovor na svježi korisnički unos u obrazac. To možemo učiniti pomoću history.replaceState.

    replaceState radi isto kao i pushState, s potpuno istim parametrima, osim što ažurira trenutni unos umjesto dodavanja novog. Mogu se sjetiti jedne situacije u našoj demonstraciji u kojoj bi se to moglo upotrijebiti: početno učitavanje stranice. Ako dovoljno dugo klikate unatrag, vidjet ćete da povratak na izvorni URL ne daje izvorni sadržaj. Popravimo to dodavanjem sljedećeg na dno naše skripte:

    // Pohranjujemo početni sadržaj kako bismo ga kasnije mogli ponovno posjetiti history.replaceState(( content: contentEl.textContent, photo: photoEl.src ), document.title, document.location.href);

    Budući da se ovo pokreće kada se stranica učita, sprema početno stanje stranice. Kasnije možemo učitati ovo stanje kada se korisnik vrati na ovu točku putem slušatelja događaja koji smo prethodno postavili. Možete ga isprobati tako da učitate stranicu, kliknete nekoliko poveznica, a zatim se vraćate dok se ne vratite na izvorni URL. Početni sadržaj se vratio!

    Demo

    Postavio sam demonstraciju našeg dovršenog koda. Također sam dodao malo pozadinske magije kako bi naši URL-ovi history.pushState funkcionirali kao prava web-lokacija. Zapamtite da URL-ovi koje gurate trebaju biti živi URL-ovi koje korisnik može označiti i dijeliti kao stvarne ulazne točke na vašu stranicu.

    Podrška za preglednik

    Ažurirane kopije Chromea (5+), Safarija (5.0+), Firefoxa (4.0+) i Opere (11.50+) imaju podršku za novi History API. Čak i neki mobilni preglednici rade dobro, poput Mobile Safarija na iOS-u 4+. Nažalost, IE 9 i starije verzije nemaju podršku, ali kad stigne.

    Safari 5.0 ponekad pokazuje jednu neobičnost: navigacija između stanja uzrokuje da se spinner za učitavanje pojavi i ostane čak i kada je stanje učitano. Ovo prestaje kada se udaljite koristeći vezu ili radnju koja ne uključuje stanje koje je spremio History API.

    Polifil

    Polifill postoji za History API. Zgodno nazvan History.js koristi HTML4 hashchange događaj s identifikatorima fragmenata dokumenta kako bi oponašao API povijesti u starijim preglednicima. Ako moderni preglednik koristi jedan od hash URL-ova, koristi replaceState za tiho ispravljanje URL-a.

    Zvuči kao magija, ali budite sigurni da ste svjesni posljedica upotrebe identifikatora fragmenata, kao što je ranije spomenuto u ovom članku. Stoga je autor History.js sastavio vodič pod nazivom Inteligentno upravljanje stanjem.

    Završne misli

    URL-ovi nadilaze samo sesiju pregledavanja korisnika. Oni su povijesno važni markeri za resurse koji bi vrlo dobro mogli ostati u upotrebi još mnogo godina. Prije nego što se upustite u razvoj JavaScripta svoje web-lokacije, trebali biste razmisliti o dizajnu svojih URL-ova. Neka budu smisleni i organizirani. Provjerite možete li im izravno pristupiti bez JavaScripta. Tek tada biste trebali dodati svoj JavaScript kako biste poboljšali iskustvo pregledavanja.

    • Kategorija
    26 odgovora na članak “Pushing and Popping with the History API”

    Doslovno sam *upravo* ovo otkrio i radio na ovome za klijenta prije dva tjedna. Čak sam razmišljao o tome da napišem blog jer mi je ovo super. Ovo stvarno može promijeniti igru.

    Iznenađen sam što niste pokrili značajku history.state? Vjerujem da je ovo trenutna specifikacija, iako radi samo u Firefoxu. Kod koji se ovdje koristi, iako radi, mislio sam da je dio originalne verzije specifikacije. Također, vrijedno je spomenuti da *trebate* proslijediti JavaScript objekt kao u vašem primjeru. Microsoftov IE blog ima primjere gdje se niz prosljeđuje. Nisam testirao podršku za ovo u svim preglednicima, ali vrijedi spomenuti.

    Doslovno vam ne mogu reći koliko je sati cijeli problem "Pohrani početni sadržaj kako bismo ga kasnije mogli pregledati" bio problem za mene. Čini mi se neintuitivnim da zadano stanje do kojeg dođete nije u hrpi povijesti.

    Isprobavam demo stranicu Internet Explorer 9 i ne mogu primijetiti nikakvu razliku u Chromeu pa se čini da radi.

    Sigurno ću koristiti ovaj članak za budući projekt. Hvala vam!

    hvala na dijeljenju iskustva, vrlo informativno.

    Možete li pojasniti što ste učinili na poslužitelju da biste obradili lažne URL-ove? Jeste li umetnuli ručna preusmjeravanja ili automatska prepisivanja? Kako se pretvaraju?

    Puno ti hvala!

    U međuvremenu sam malo napredovao na istoj temi. Ako je vaš web poslužitelj Apache, možete ga konfigurirati da koristi mod_rewrite, koji omogućuje pretvaranje URL-ova koje je upisao korisnik (ili alat za indeksiranje) u URL-ove na strani drugog poslužitelja:

    To se postiže dodavanjem niza pravila u .htaccess u korijenu vaše web stranice.

    Doslovno, upravo sam objavio svoju novu stranicu koja koristi ovu tehniku. Djeluje prekrasno!

    Lijepo je (možda) moći ukloniti hashove i hashbangove na budućim stranicama temeljenim na ajaxu.

    Stvarno se veselim vidjeti kako će se ovo koristiti kako bude šire prihvaćeno.

    Jedini problemi nastaju (kao što je često slučaj) s implementacijama ovoga na više preglednika. API povijesti možda podržavaju preglednici koje ste spomenuli, ali s različitim stupnjevima uspjeha.

    Pogledajte History.js (obratite pažnju na veliko 'H') Bena Luptona ovdje: https://github.com/balupton/History.js/ koji nudi način korištenja HTML5 stanja povijesti dok uzima u obzir nedosljednosti craoos preglednika.

    Opet, odličan članak. Stvarno se svodi na temeljna načela.

    Ovo je sjajno, ali ako ne radi na IE9 ili nižem, trenutno je prilično beskorisno za produkcijske stranice (bez puno neurednih hakiranja i zamjena!)

    @Raphael+Eric:

    Ispričavam se na kasnom odgovoru! Za potrebe demonstracije koristio sam vrlo osnovnu mod_rewrite i PHP postavku.

    RewriteRule ^(fluffy|socks|whiskers|bob)$ index.php?p=$1

    Gore navedeno pravilo prepisivanja maskira demo URL-ove i prosljeđuje ih u jednu PHP datoteku s nizom upita koju mačku korisnik pokušava vidjeti. PHP datoteka zatim provjerava je li $_GET["p"] važeći (uvijek dezinficirajte i provjerite svoj unos prema potrebi), a zatim koristi unaprijed definirane varijable koje sam postavio za tu mačku.

    Da je ovo prava aplikacija, traženi put bi se mogao koristiti za konstruiranje upita baze podataka (naravno saniranih) za povlačenje dinamičnijeg sadržaja. CMS poput WordPressa koristi nešto poput ovoga za implementaciju "čistog URL-a".

    Nadam se da ovo pomaže.

    Da li bi se moglo vidjeti tu htaccess datoteku bliže. Razumijem sve što se ovdje događa, unutar dijela povijesti API-ja, osim mod_rewrite. Imate li zapravo još stranica koje negdje žive za svaku od ovih različitih mačaka? Osvježavanje stranice nakon što kliknete nekoliko mačaka vraća pogrešku Stranica nije pronađena. Ovo ima veze s htaccess dijelom koji mi nedostaje, zar ne? Hvala.

    Unatoč mom gornjem komentaru o slaboj podršci preglednika, odlučio sam se prebaciti s raspršenih URL-ova (/#/slug) na HTML5 povijest za http://goproheroes.com i odlučio sam se jednostavno vratiti na normalno učitavanje stranice za IE9 i niže koristeći:

    funkcija supports_history_api() (
    return !!(window.history && history.pushState);
    }

    Hvala Mike, tvoj mi je demo pomogao. Imao sam svoj pokušaj malo kompliciraniji nego što je trebao biti.

    Međutim, pokušavam pratiti i otkriti kada korisnik korača naprijed i natrag kroz povijest kako bih svojoj stranici mogao dodati odgovarajuće prijelaze. Nažalost, API za povijest ne dopušta vam da znate je li na popstate događaju kliknuto dugme naprijed ili natrag. To bi stvarno bilo od pomoći.

    Mislim da bi kolačić mogao biti jedini način da se pokuša pratiti narudžba. Spremanje prethodne varijable u objekt stanja kompliciralo je stvari i uzrokovalo probleme s preglednikom.

    Dodavanje na popis,
    Hvala Mike!

    Ti preslatki mačići pomogli su mi da postavim neke funkcije guranja i iskakanja na novoj verziji moje stranice koja će uskoro biti objavljena!

    Hvala na tutu!

    U vašoj funkciji obrađivača klikova nešto nije u redu u vašem poštanskom broju (ipak je u redu na kittielandu):

    1. Objekt događaja je deklariran na argumentima kao "e", a ne kao "event".

    2. Nema updateContent(); bilo gdje! Morao sam provjeriti vaš radni izvor da vidim radim li nešto krivo.

    Ali čekajte, ima još! ...također neka ažuriranja:

    3. Chrome 19+ počinje se miješati s vlasništvom stanja događaja i slično.

    Kao savjet: upotrijebio sam jadni setTimeout() za vezanje slušatelja događaja kako bih preskočio Chromeovu želju da prikaže svoje stanje.

    Najbolji članci na temu