Buona esercitazione per l'utilizzo dell'API History HTML5 (Pushstate?) [Chiuso]


168

Sto cercando di utilizzare l'API History HTML5 per risolvere problemi di deep linking con il contenuto caricato AJAX, ma sto lottando per decollare. Qualcuno sa di buone risorse?

Voglio usare questo in quanto sembra un ottimo modo per consentire alla possibilità di coloro che vengono inviati che i collegamenti potrebbero non avere JS attivato. Molte soluzioni falliscono quando qualcuno con JS invia un collegamento a qualcuno senza.

La mia ricerca iniziale sembra indicare un'API History all'interno di JS e il metodo pushState.

http://html5demos.com/history

Risposte:


181

Per un grande tutorial, la pagina Rete di sviluppatori Mozilla su questa funzionalità è tutto ciò di cui hai bisogno: https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history

Sfortunatamente, l'API History HTML5 è implementata in modo diverso in tutti i browser HTML5 (rendendola incoerente e buggy) e non ha fallback per i browser HTML4. Fortunatamente, History.js fornisce compatibilità incrociata per i browser HTML5 (garantendo che tutti i browser HTML5 funzionino come previsto) e facoltativamente fornisce un hash-fallback per i browser HTML4 (incluso il supporto mantenuto per dati, titoli, funzionalità pushState e ReplaceState).

Puoi leggere di più su History.js qui: https://github.com/browserstate/history.js

Per un articolo sull'API Hashbangs VS Hash VS HTML5 History, consultare qui: https://github.com/browserstate/history.js/wiki/Intelligent-State-Handling


25
Auto-spina spudorata. Post e plugin eccellenti però. :)
Purag,


28

Tieni a mente mentre usi HTML5 pushstate se un utente copia o aggiunge un segnalibro a un link diretto e lo visita di nuovo, quindi sarà un hit diretto del server che sarà 404 quindi devi essere pronto per questo e anche una libreria js pushstate non aiuterà tu. La soluzione più semplice è aggiungere una regola di riscrittura al tuo server Nginx o Apache in questo modo:

Apache (nel tuo vhost se ne usi uno):

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]
 </IfModule>

nginx

rewrite ^(.+)$ /index.html last;

Questa è la vera risposta. Questo non è da nessuna parte nel wiki / tutorial di History.js di Balupton, ecc. In realtà History.js non usa l'hash, quindi è necessario utilizzare un reindirizzamento .htaccess!
adriendenat,

13
Idealmente il tuo server / app dovrebbe rispondere al percorso in modo appropriato senza la necessità di questa riscrittura.
Sholsinger,

Concordato, tranne nel caso di molti moderni framework JavaScript come Backbone.js, Spine, Ember, ecc. Queste sono essenzialmente applicazioni JavaScript "a una pagina". Si potrebbe trovare una soluzione per servire il modello di backend di scrittura per SEO, ect, ma nel frattempo questo sarebbe necessario.
Mauvis Ledford,

*giusto. Scrivo di questo in modo più dettagliato qui: readystate4.com/2012/05/17/…
Mauvis Ledford

6

Le specifiche della cronologia HTML5 sono bizzarre.

history.pushState()non invia un popstateevento o carica una nuova pagina da solo. Doveva solo spingere lo stato nella storia. Questa è una funzione "annulla" per le applicazioni a pagina singola. Devi inviare manualmente un popstateevento o utilizzare history.go()per passare al nuovo stato. L'idea è che un router può ascoltarepopstate eventi e fare la navigazione per te.

Alcune cose da notare:

  • history.pushState()e history.replaceState()non spedirepopstate eventi.
  • history.back(), history.forward()e i pulsanti avanti e indietro del browser invianopopstate eventi.
  • history.go()e history.go(0)ricaricare l'intera pagina e non spedirepopstate eventi.
  • history.go(-1)(indietro di 1 pagina) e history.go(1)(avanti di 1 pagina) eseguono popstateeventi di invio .

È possibile utilizzare l'API di cronologia in questo modo per inviare un nuovo stato E inviare un evento popstate.

history.pushState({message:'New State!'}, 'New Title', '/link'); window.dispatchEvent(new PopStateEvent('popstate', { bubbles: false, cancelable: false, state: history.state }));

Quindi ascolta gli popstateeventi con un router.


1
Sono solo io o new PopStateEvent(...)sembra non funzionare in IE11? C'è una soluzione alternativa che qualcuno conosce?
David Alan Hjelle,

Sembra che IE 11 abbia bisogno di qualcosa del tipo: var pop_state_event = document.createEvent('Event'); pop_state_event.initEvent('popstate', true, true); window.dispatchEvent(pop_state_event);
David Alan Hjelle,

4

Puoi provare Davis.js , ti dà il routing nel tuo JavaScript usando pushState quando disponibile e senza JavaScript consente al tuo codice lato server di gestire le richieste.



2

Potresti dare un'occhiata a questo plugin jQuery. Hanno molti esempi sul loro sito. http://www.asual.com/jquery/address/


Ancora una volta, questa soluzione sembra fallire quando JS è spento. Penso che l'API di storia abbia il potere di lavorare insieme a modrewrite in modo che i collegamenti vengano sempre elaborati in prima istanza dal server, senza bisogno di reindirizzamento dal livello JS.
Lieve Fuzz,

Sei sulla strada giusta con il modrewrite. La soluzione di gestione dell'API della cronologia e gestione quando l'utente non ha JS sono due cose separate. Se non si dispone di JS, è necessario gestire l'utente con hrif e risposte server standard. L'API della cronologia potrebbe essere costruita come una sorta di "bello da avere" se il browser dell'utente lo supporta.
Nathan Totten,

I campioni Express e State forniti con jQuery Address 1.3 funzionano abbastanza bene quando JavaScript è disabilitato. Il secondo usa PHP con mod_rewrite.
Rostislav,

Esatto il mio tatto. Intendo costruire il sito senza JS, aggiungere elementi AJAX e quindi utilizzare la cronologia per riscrivere l'URL, preservando i collegamenti diretti. Teoricamente, dovrebbe essere un metodo migliore di quello che ho visto in quanto il sito non dipenderà da AJAX, in nessuna fase
Mild Fuzz,

1
-1 come jQuery Address non è una porta diretta dell'API di stato HTML5 - non supporta dati o titoli e sostituisceStato.
Balupton,

2

Ho scritto un'astrazione del router molto semplice su History.js , chiamata StateRouter.js . È nelle prime fasi di sviluppo, ma lo sto usando come soluzione di routing in un'applicazione a pagina singola che sto scrivendo. Come te, ho trovato History.js molto difficile da comprendere, soprattutto perché sono abbastanza nuovo in JavaScript, fino a quando ho capito che hai davvero bisogno (o dovresti avere) un'astrazione di routing su di esso, poiché risolve un livello basso problema.

Questo semplice codice di esempio dovrebbe dimostrare come viene utilizzato:

var router = new staterouter.Router();
// Configure routes
router
  .route('/', getHome)
  .route('/persons', getPersons)
  .route('/persons/:id', getPerson);
// Perform routing of the current state
router.perform();

Ecco un piccolo violino che ho inventato per dimostrarne l'utilizzo.


1
Questo violino non funziona per me in Chrome su Mac. Genera un errore. (Errore di riferimento non rilevato: staterouter non definito)
DrewT

@DrewT Grazie, il violino è stato rotto a causa di un cambiamento su github.com, ma ci ho lavorato.
aknuds1,

Sì, ora lavoro grazie per la rapida risposta.
Estratto il

1

se jQuery è disponibile, è possibile utilizzare jQuery BBQ


Questo sembra fallire con JS spento.
Lieve Fuzz,

questo è probabilmente vero - non ci ho pensato. Penserei che avrai quel problema con tutti gli approcci basati su js-library. Si basano sulla manipolazione della parte hash dell'URL.
Sprugman,

1
questo è il punto dell'API History HTML5 - non rompe nulla
balupton,

2
@MildFuzz Il computer sembra non funzionare senza alimentazione! Penso che tu abbia un errore ID-10-T ...
Eric Hodonsky,

1
Ironia della sorte, sei tu che hai incomprensioni
Mild Fuzz
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.