Una semplice introduzione alla Storia API in JavaScript

La storia API è una di quelle tecniche JavaScript che ogni sviluppatore web ha bisogno di conoscere freddo. Senza di esso, un solo clic del pulsante Indietro salterà direttamente dalla tua applicazione. Perderai qualsiasi lavoro in corso e l’utente sarà costretto a ricominciare tutto da capo.

Fortunatamente, c’è una soluzione facile. Fin dalla formalizzazione di HTML5 (e il rilascio di Internet Explorer 10), abbiamo avuto un’API Cronologia che consente di aggiungere all’elenco cronologia e reagire alla navigazione avanti e indietro. In questo articolo, imparerai come funziona e lo proverai con un esempio dal vivo.

Ma prima di andare avanti, diamo un’occhiata più da vicino al problema.

Ai vecchi tempi del web, una pagina web ha fatto una cosa: visualizzare cose. Quando volevi guardare qualcos’altro, hai fatto clic su un link e sei andato a un nuovo URL.

Come JavaScript è cresciuto più potente, gli sviluppatori si sono resi conto che ogni pagina web potrebbe essere un’applicazione completa a sé stante. Una pagina web potrebbe rivaleggiare con un’applicazione desktop! Il problema era che i pulsanti Indietro e Avanti nel browser non si adattavano a questo nuovo modello di applicazione. Ad esempio, un utente potrebbe eseguire una sequenza di attività in un’applicazione Web a pagina singola e quindi aspettarsi di utilizzare il pulsante Indietro per tornare indietro di un singolo passaggio. Invece, il pulsante Indietro tornerebbe alla pagina Web precedente, chiudendo efficacemente l’app JavaScript nel mezzo di qualsiasi cosa stesse facendo.

Spesso, questo comportamento non era intuitivo. Ad esempio, si consideri un’applicazione che utilizza l’oggetto XMLHttpRequest per recuperare nuovi dati e aggiornare la pagina. Per l’utente, potrebbe sembrare che stiano viaggiando verso una nuova pagina. Ma se commettono l’errore di usare il pulsante Indietro, l’illusione è in frantumi e tutto va di traverso.

diamo un’occhiata più da vicino. Ecco un esempio che ti consente di sfogliare il Dictionnaire Infernal, un famoso (e ora di pubblico dominio) libro del 1818 che descrive strane bestie dalla superstizione e dalla mitologia. Il trucco è che i link precedenti e successivi non ti portano a un’altra pagina. Invece, attivano una chiamata asincrona tramite XMLHttpRequest che ottiene le informazioni per la diapositiva successiva. Quindi, il codice JavaScript aggiorna la casella di scorrimento, senza disturbare il contenuto sul resto della pagina.

Ecco una versione live dell’esempio, completa di supporto API Storia. Anche se tutto si svolge in una singola pagina web, è possibile utilizzare i pulsanti Avanti e indietro per passare senza problemi da un’immagine all’altra. È anche possibile utilizzare il pulsante Ricarica (ricarica la diapositiva corrente, piuttosto che riavviare l’intera applicazione), ed è possibile inserire i segnalibri che mantengono lo stato corrente — in altre parole, ti portano subito indietro alla diapositiva che si sta attualmente guardando.

Ed ecco una versione vecchia scuola dell’esempio che non utilizza l’API della cronologia. Non importa quanto sei nello spettacolo laterale – quando si utilizza il pulsante Indietro, si torna alla pagina Web precedente. I pulsanti Avanti e Ricarica sono ugualmente rotti. I segnalibri riavviano l’app dall’inizio.

È possibile scaricare tutto il codice sorgente qui per giocare con. (Tuttavia, non funzionerà localmente, perché utilizza l’oggettoXMLHttpRequest per effettuare richieste web.) Nel resto di questo articolo, analizzerò come funziona tutto.

Preparazione dell’esempio

Prima di entrare nell’API della cronologia, è importante avere una comprensione di base di come funziona questo esempio. È tutto piuttosto semplice.

La pagina utilizza un numero per tenere traccia della diapositiva che sta attualmente mostrando. Quando si fa clic su Avanti o Precedente, il codice cambia il numero di diapositiva corrente. Quindi utilizza la propria funzionegoToSlide() per aggiornare la pagina.

La funzione goToSlide() è dove avviene il vero lavoro. Avvia una richiesta asychronous utilizzando il famigerato XMLHttpRequest oggetto.

Spetta a te decidere come viene generato il contenuto della diapositiva e inviato al codice chiamante nella pagina. Di solito, avrai una sorta di framework di routing che attiva il giusto codice lato server. Quel codice lato server può quindi afferrare il contenuto della diapositiva da una cache, un database, un file o anche un blocco di markup hard-coded.

In questo esempio, ho mantenuto le cose il più semplici possibile. La richiesta acquisisce il markup HTML da un file statico. Quindi, se stai richiedendo la terza diapositiva (con un URL relativo come Slides/3), ottieni un frammento di markup HTML solo per quella diapositiva. Piano!

Al termine della richiesta, il browser attiva il gestore di eventi newSlideReceived(). Quindi è semplicemente una questione di prendere il markup ricevuto e inserirlo nella pagina, usando un segnaposto<div>.

Questo è tutto ciò che devi sapere per creare la versione ingenua di questa pagina, che non supporta la cronologia del browser.

L’oggetto history

L’oggettohistory esiste quasi dagli albori di JavaScript. Ma per gran parte della sua vita, è stato molto meno potente (e molto meno utile) di quanto lo sia oggi.

L’oggetto originale history ha solo una proprietà e tre metodi di base. La proprietà è length, e ti dice quante voci ci sono nell’elenco della cronologia del browser:

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

Questo dettaglio è per lo più inutile.

tre history metodi back() (invia un visitatore di un passo indietro nella cronologia di navigazione), forward() (invia un visitatore uno step in avanti) e go() (prende un valore di scostamento, che indica al browser come molti passi per andare avanti o indietro). Tutto questo aggiunge fino a relativamente poco, a meno che non si desidera progettare il proprio personalizzato indietro e avanti pulsanti su una pagina web.

La HistoryAPI aggiunge due ingredienti molto più utili: il metodopushState() e l’eventoonPopState.

Aggiunta di una voce all’elenco cronologia

Il metodopushState() è il fulcro dell’API Cronologia. Esso consente di aggiungere un nuovo elemento nella lista cronologia per la pagina corrente. Ecco cosa simile:

A questo punto, ci si potrebbe chiedere — qual è il punto di avere più di una voce per la stessa pagina? Il trucco è che ogni voce ha qualche stato collegato con esso – un pezzo collegato di informazioni o oggetto che si imposta. Quando l’utente fa un passo indietro attraverso l’elenco della cronologia, si ottengono le informazioni sullo stato corrispondente in modo da poter riportare la pagina alla versione precedente.

Il metodo pushState() accetta tre argomenti:

  • Data. Il primo argomento è qualsiasi pezzo di dati che si desidera memorizzare per rappresentare lo stato corrente di questa pagina. Utilizzerai queste informazioni per ripristinare la pagina quando l’utente torna indietro attraverso l’elenco della cronologia.
  • Titolo. Il secondo argomento è il titolo della pagina che si desidera che il browser per mostrare. Attualmente, tutti i browser sono unificati ignorando questo dettaglio. (Quindi puoi semplicemente passare null.)
  • URL. Il terzo argomento è la nuova versione dell’URL che si desidera mostrare per la pagina nella barra degli indirizzi del browser. Ciò consente di aggiungere un migliore supporto per il pulsante Ricarica e segnalibri del browser.

Nell’esempio Dictionnaire Infernal slideshow, è facile aggiungere il supporto della cronologia Tutto ciò che serve per tenere traccia è il numero di diapositiva. Si aggiunge all’elenco cronologia ogni volta che la diapositiva cambia.

Ecco la riga di codice che devi aggiungere:

history.pushState(slideNumber, null, null);

Noterai che questo codice non cambia il titolo della pagina con il secondo argomento (perché non funziona comunque) e non cambia l’URL (vedrai come farlo in un momento). Tutto ciò che fa è memorizzare il numero di diapositiva.

Per l’immagine completa, ecco le due chiamate a history.pushState() div — nel loro posto corretto – i gestori di eventi per i collegamenti successivi e precedenti:

Tornando a una pagina precedente

Quando si utilizza il metodo pushState(), è anche necessario pensare alla sua controparte naturale, l’evento onPopState. Mentre il metodopushState() inserisce una nuova voce nell’elenco della cronologia del browser, l’eventoonPopState ti dà la possibilità di gestirlo quando l’utente ritorna.

Per capire come funziona, considera cosa succede se un visitatore passa attraverso tutte le diapositive nell’esempio Infernale di Dictionnaire. Quando ogni nuova diapositiva viene caricata, la pagina aggiunge una voce di cronologia. Ma se l’utente fa un passo indietro con il pulsante Indietro, non succede nulla.

Per correggere questa lacuna, è necessario gestire l’evento onPopState, che viene attivato dopo ogni navigazione della cronologia. (Questo include se si utilizza uno dei metodi di cronologia, come history.back(), così come quando l’utente fa clic sui pulsanti di navigazione del browser.)

L’eventoonPopState fornisce al codice le informazioni sullo stato memorizzate in precedenza conpushState(). In questo caso, questo è solo il numero di diapositiva, che puoi prendere dalla proprietà state dell’argomento evento, in questo modo:

var slideNumber = e.State;

Il tuo compito è usare le informazioni sullo stato per ripristinare la versione corretta della pagina. Nell’esempio corrente, ciò significa caricare la diapositiva corrispondente chiamando la comoda funzione goToSlide() che gestisce tutta la navigazione della diapositiva. Il codice completo è breve e diretto:

si Noti che è necessario verificare se e.Statenull che succede su alcuni browser quando la pagina viene caricata per la prima volta e non c’è stato salvato.

Modifica dell’URL

La versione corrente di questo esempio supporta l’elenco della cronologia ma non funziona bene con il pulsante Ricarica. Ad esempio, se fai clic sulla terza diapositiva e poi aggiorni la pagina, finirai di nuovo all’inizio. Vi troverete nella stessa situazione se si tenta di segnalibro una delle diapositive — tornare al segnalibro e si inizierà di nuovo sulla prima diapositiva.

La soluzione a questi problemi consiste nell’utilizzare l’API History per modificare l’URL. Ma c’è una ragione importante per cui ho lasciato questo passo fino all’ultimo. Spesso, gli esempi che utilizzano l’API Cronologia cambiano l’URL ma non utilizzano il nuovo URL. Ciò può portare a un’app Web che si interrompe quando l’utente la aggiorna (con un brutto errore 404) o passa a una versione simile ma leggermente diversa della pagina. Se non sei sicuro di come gestire URL diversi, non c’è vergogna nell’utilizzare l’approccio semplificato dell’esempio precedente.

Quindi diciamo che sei pronto per immergerti, creare URL migliori e giocare bene con i segnalibri e gli aggiornamenti del browser. Ci sono due approcci di base che puoi adottare:

  • Cambia del tutto il nome della pagina URL. Nell’esempio Dictionnaire Infernal, è possibile modificare l’URL in Slide1.html, Slide2.html, e così via come l’utente si muove attraverso le diapositive. Il problema è che è necessario disporre di pagine effettive con questi nomi (non farlo, è ingombrante), oppure è necessario impostare il routing in modo che quando il server Web riceve una richiesta per Slide2.html esegue il codice che crea la versione corretta della pagina.
  • Mantenere lo stesso nome della pagina, ma aggiungere informazioni alla stringa di query. Questo è un approccio più semplice e su scala ridotta. Mentre l’utente viaggia attraverso la presentazione, ti ritroverai con URL come PRESENTAZIONE.html?slide=1, quindi SlideShow.html?slide=2, presentazione.html?slide=3, e così via. Il vantaggio di questo approccio è che è banalmente facile scrivere un piccolo pezzo di JavaScript che controlla la stringa di query e si assicura di essere sulla diapositiva giusta quando la pagina viene ricaricata. Non è necessario alcun codice server per farlo funzionare: una pagina può fare tutto.

Ecco una versione modificata della chiamatapushState() che hai visto in precedenza che utilizza il secondo approccio. Questo codice inserisce il numero di diapositiva alla fine dell’URL:

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

Ed ecco il codice che viene eseguito quando la pagina viene ricaricata. Controlla le informazioni sulla diapositiva nell’URL e, se trova un numero corretto, chiama la funzione goToSlide() per caricare la diapositiva.

Ora non perderai mai il tuo posto nella presentazione. Puoi provare la versione completa di questo esempio o scaricare tutto qui.

Dettagli finali

L’API History è facile da usare, ma rende anche facile creare problemi più grandi che si risolvono. Ora che sai come tutto si adatta, ecco alcuni consigli finali:

  • Se si preme, è necessario pop. Il metodopushState() e l’eventoonPopState sono partner. Quello che hai messo in uno, si torna con l’altro.
  • Non modificare l’URL a meno che tu non sia pronto a gestirlo. È bello cambiare il tuo URL per riflettere la tua pagina che cambia, ma devi essere in grado di gestire le richieste per ogni URL che usi. Se il tuo URL punta a una pagina che non esiste, l’applicazione si interromperà su aggiornamenti e segnalibri.
  • Utilizzare un oggetto stato personalizzato per memorizzare ulteriori informazioni. Non è necessario attaccare con un numero semplice. È possibile inserire un intero oggetto personalizzato in stato, che può raggruppare tutte le informazioni necessarie per un’attività complessa.



Lascia un commento

Il tuo indirizzo email non sarà pubblicato.