2015-01-19 9 views
23

Utilizzando l'API html5 window.history, posso controllare abbastanza bene la navigazione sulla mia web app.JS - window.history - Elimina uno stato

L'applicazione ha attualmente due stati: selectDate (1) e enterDetails (2).

Quando i carichi app, ho replaceState e impostare un popState ascoltatore:

history.replaceState({stage:"selectDate",...},...); 
window.onpopstate = function(event) { 
    that.toStage(event.state.stage); 
}; 

Quando si seleziona una data e l'applicazione passa alla fase 2 Spingo stato 2 alla pila:

history.pushState({stage:"enterDetails",...},...); 

Questo stato viene sostituito ogni volta che i dettagli cambiano e quindi vengono salvati nella cronologia.

Ci sono tre modi per lasciare la fase 2:

  • save (Ajax presentare)
  • annullare
  • indietro pulsante

Il pulsante indietro viene gestito dal popstate ascoltatore. Il pulsante Annulla spinge lo stage 1 in modo che l'utente possa tornare ai dettagli che stavano inserendo il pulsante Indietro. Funzionano entrambi bene.

sul pulsante Salva dovrebbe tornare al livello 1 e non permettere all'utente di navigare indietro alla Pagina (dal momento che già presentate). In pratica, è necessario che lo stack della cronologia sia lunghezza = 1.

Ma non sembra essere uno history.delete() o history.merge(). Il meglio che posso fare è un history.replaceState(stage1) che lascia la pila della storia come: ["selectDate","selectDate"].

Come si elimina un livello?

Edit:

pensiero di qualcos'altro, ma non funziona neanche.

history.back(); //moves history to the correct position 
location.href = "#foo"; // successfully removes ability to go 'forward', 
         // but also adds another layer to the history stack 

Questo lascia la pila storia come ["selectDate","selectDate#foo"].

Quindi, in alternativa, c'è un modo per rimuovere la cronologia "Avanti" senza premere un nuovo stato?

risposta

34

A questo punto è possibile che ci sia già stato, ma ... per quanto ne so non c'è modo di cancellare una voce di cronologia (o stato).

Un'opzione che ho esaminato è quella di gestire la cronologia in JavaScript e utilizzare l'oggetto window.history come operatore di sorta.

Fondamentalmente, quando la pagina viene caricata si crea l'oggetto storia personalizzato (andremo con una serie qui, ma l'uso qualunque cosa ha un senso per la propria situazione), poi fare il vostro primo pushState. Vorrei passare l'oggetto della cronologia personalizzata come oggetto stato, in quanto potrebbe rivelarsi utile se devi anche gestire gli utenti che si allontanano dalla tua app e tornano più tardi.

var myHistory = []; 

function pageLoad() { 
    window.history.pushState(myHistory, "<name>", "<url>"); 

    //Load page data. 
} 

Ora, quando si naviga, si aggiunge al tuo proprio oggetto la storia (o non fare - la storia è ora nelle vostre mani!) E utilizzare replaceState per tenere il browser fuori dal giro.

function nav_to_details() { 
    myHistory.push("page_im_on_now"); 
    window.history.replaceState(myHistory, "<name>", "<url>"); 

    //Load page data. 
} 

Quando l'utente si sposta all'indietro, saranno colpire il vostro stato di "base" (il vostro oggetto di stato sarà null) e si può gestire la navigazione in base al vostro oggetto la storia personalizzato. In seguito, fai un altro pushState.

function on_popState() { 
    // Note that some browsers fire popState on initial load, 
    // so you should check your state object and handle things accordingly. 
    // (I did not do that in these examples!) 

    if (myHistory.length > 0) { 
     var pg = myHistory.pop(); 
     window.history.pushState(myHistory, "<name>", "<url>"); 

     //Load page data for "pg". 
    } else { 
     //No "history" - let them exit or keep them in the app. 
    } 
} 

L'utente non sarà mai in grado di navigare in avanti con i loro pulsanti del browser perché sono sempre sulla pagina più recente.

Dal punto di vista del browser, ogni volta che tornano indietro, si sono immediatamente spinti in avanti.

Dal punto di vista dell'utente, sono in grado di navigare all'indietro attraverso le pagine ma non in avanti (praticamente simulando il modello "stack di pagine" dello smartphone).

Dal punto di vista dello sviluppatore, ora avete un alto livello di controllo sul modo in cui l'utente naviga attraverso l'applicazione, consentendo comunque loro di utilizzare i pulsanti di navigazione familiari sul proprio browser. Puoi aggiungere/rimuovere elementi da qualsiasi posizione nella catena della cronologia come preferisci. Se si utilizzano oggetti nell'array della cronologia, è possibile tenere traccia anche di ulteriori informazioni sulle pagine (come il contenuto dei campi e quant'altro).

Si potrebbe anche estendere l'idea di gestire la navigazione in avanti. Avresti bisogno di 3 pagine: una pagina di gestione "indietro", una pagina di gestione "avanti" e una pagina di "riposo" tra di loro in cui l'utente sarà in genere. Dovresti quindi attraversare avanti e indietro lungo l'oggetto della cronologia invece di spingere/saltare gli oggetti.

+0

Ehi, grazie. È piuttosto più elegante di quello che ho usato come soluzione alternativa. – slicedtoad

+0

Cosa fare quando un utente è abituato a questo comportamento, quindi naviga alcune volte costruendo uno stato, quindi naviga verso un sito esterno, quindi torna indietro e presumo che la cronologia di tutte le applicazioni della navigazione sia scomparsa e il pulsante Indietro essere ultimo sul mucchio. –

+0

Lo stato inviato da history.pushState sarà disponibile al loro ritorno (anche se chiudono o aggiornano il browser). Alcuni browser generano un evento popstate al caricamento della pagina, ma altri no (Firefox per esempio). Ma puoi sempre leggere history.state direttamente. Se non stai facendo uso dell'oggetto history.state, avresti bisogno di usare un altro mezzo per mantenere il tuo stato (come localStorage). history.state viene mantenuto automaticamente come parte della cronologia di navigazione. –

Problemi correlati