2013-04-23 10 views
5

ho usato (https://github.com/browserstate/history.js) e hanno un pezzo di codice come questodel browser avanti e indietro non richiamare il metodo di callback con evento stateChange di history.js

History.Adapter.bind(window, 'statechange', function() { 
    var State = History.getState(); 
    alert('Inside History.Adapter.bind: ' + State.data.myData); 
}); 

function manageHistory(url, data, uniqueId){ 
    var History = window.History; 
    if (!History.enabled) { return false; }   
    History.replaceState({myData: data}, null, '?stateHistory=' + uniqueId); 
} 

se invoco manageHistory() dopo la mia chiamata AJAX, quindi Il metodo di callback History.Adapter.bind viene richiamato correttamente. Tuttavia, se faccio clic sul browser indietro e poi sul pulsante di avanzamento, il risultato di spostamento della pagina da B a A è , quindi A torna a B, il metodo di richiamata all'interno di History.Adapter.bind non viene richiamato. Questo succede sia su Chrome che su IE9. Qualcuno sa come risolvere questo problema, ho bisogno di ottenere il State dopo aver fatto clic sul browser indietro e poi in avanti, per aggiornare il mio DOM. Si prega di aiutare

Nota: io uso la versione 1.7.1 jquery.history.js per il browser HTML4 IE9

UPDATE (3 maggio 2013): parlare un po 'di più sulla mia esigenza

Spiacente Ero impegnato con altri compiti, che non fino ad ora ho a volte a guardare questo problema. Quindi, oncomplete di una chiamata Ajax, ho preso quell'informazione che ritorna da me e la spingo nello stato. Il mio requisito è: che se navigo dalla pagina A alla pagina B, e poi alla pagina B, eseguo numeri di richieste ajax che risultano nella manipolazione DOM (chiamiamo ogni richiesta ajax che risulta nella manipolazione DOM a state). Se faccio clic sul pulsante Indietro, dovrei tornare alla pagina A, e se clicco sul pulsante avanti, dovrei andare alla pagina B con l'ultimo stato in cui mi trovavo.

Quindi il mio pensiero era, oncomplete del mio richiesta Ajax, vorrei sostituire l'ultimo stato nella storia con il mio stato attuale (il mio oggetto json è l'html che ricevo indietro dalla richiesta Ajax). Se utilizzo lo stato push, diciamo che sono nella pagina B e faccio clic su un pulsante, la mia pagina ora cambia in aaa, I pushState aaa. Quindi se faccio clic su un altro pulsante, la mia pagina ora cambia in bbb, I pushState bbb. Se faccio clic sul pulsante Indietro ora, sarei ancora sulla pagina B, con il mio stato in History.Adapter.bind(window, 'statechange', function() {}) visualizzato come aaa, se faccio di nuovo clic su pulsante, vorrei andare alla pagina A. Non voglio questo comportamento. Voglio che se io sono sulla pagina B con stato bbb, e fare clic indietro, vorrei andare alla pagina A, e se faccio clic avanti, vorrei andare alla pagina B con stato bbb. Spero che questo abbia più senso. Please help

+0

Re: l'aggiornamento - penso che non si desidera utilizzare la storia per tracciare "i cambiamenti di stato" all'interno pagina B/A. utilizza la cronologia solo in combinazione con una modifica del tuo URL. Qualsiasi stato cambia all'interno di un singolo url (cioè A vs B) dovrebbe salvare lo stato da un altro meccanismo (non da history.replaceState(); ... Questo è molto facile da fare con una libreria MV * come Backbone o Angular. – 1nfiniti

+0

Check out jquery-mobile, hanno un modo ajaxy di gestire le pagine che potresti trovare utili: http://jquerymobile.com/ – euxneks

risposta

3

Vedo che si sta utilizzando History.replaceState che rimuove l'ultimo stato cronologico nello stack e lo sostituisce in base allo stato indicato nei parametri.

Sto utilizzando History.pushState nel mio sito Web e non si trova di fronte a un problema di questo tipo perché questa funzione non carica l'ultimo stato ma aggiunge il nuovo stato sopra di esso. Sta facendo funzionare correttamente i pulsanti back-forward.

Spero che ti aiuti.

Edit: Utilizzando l'esempio di change of select tag come listenner evento:

function manageHistory(url, data, uniqueId){ 
    var History = window.History; 
    if (!History.enabled) { return false; }   
    History.replaceState({myData: data}, null, '?stateHistory=' + uniqueId); 
} 

$('select.select').change(function(e) { 

    e.preventDefault(); 

    // get url 
    // get data 
    // get uniqueId 

    manageHistory(url, data, uniqueId) 


}); 

History.Adapter.bind(window, 'statechange', function() { 
    var State = History.getState(); 
    // Launch the ajax call and update DOM using State.data.myData 
}); 
+0

il fatto è che, con il mio requisito, non posso usare pushState. Se uso pushState, il pulsante indietro tornerà ad ogni richiesta Ajax, ma il mio requisito è un po 'diverso, voglio solo salvare l'ultimo stato –

+0

Penso che non abbiamo la stessa comprensione di history.js. Quello che so è che i pulsanti del browser torneranno alla Ajax richiesta se History.Adapter.bind è una richiesta Ajax con un clic del mouse.Se si desidera salvare solo l'ultimo stato, utilizzare semplicemente pushState e non associare nulla.Spiace che io sia davvero nuovo a questo. –

+0

Inoltre vedo che tu dici: if I invocare manageHistory() dopo il mio aj ax call ... Penso che dovresti eseguire la tua chiamata ajax all'interno di managehistory dopo aver premuto lo stato nello stack –

5

Quello che dovete fare è la seguente:

  • Se la pagina da cui provieni è un'altra pagina (ad esempio, apri la pagina B e la pagina precedente era la pagina A) fai un pushState.
  • Se invece la pagina precedente era la stessa pagina in cui ci si trova attualmente, si eseguirà semplicemente un replaceState, sostituendo le informazioni con le informazioni sul proprio stato corrente.

(il tracking della pagina precedente è necessario fare manualmente in qualche variabile)

Ciò significa che se si va da A a B (pushState) al nuovo stato di B (replaceState) , pulsante indietro (passa a informazioni sullo stato di A) e avanti (passa allo stato più recente di B). Inoltre, se apri A la prima volta, devi fare uno replaceState con informazioni sullo stato di A in modo che A abbia almeno uno stato (altrimenti avrà un oggetto dati vuoto).

Potrebbe essere utile guardare il mio this answer, che è semplicemente il modo in cui si sarebbe costruito uno stack cronologico ordinato con pushStates. Non esattamente quello che vuoi, ovviamente, ma è un po 'più semplice scritto e insieme alle informazioni contenute in questa risposta dovrebbe darti il ​​comportamento che desideri.

+0

@Whoever mi ha downvoted ... sarebbe davvero bello sapere perché, perché ho affrontato la domanda esattamente ... –

2

Inoltre,

relpaceState sarà sempre cancellerà stato B.

Utilizzare pushState per gli stati A e B.

E utilizzare replacestate per gli stati aaa, bbb, ccc.

function manageHistoryBack(url, data, uniqueId){ 
    var History = window.History; 
    if (!History.enabled) { return false; }   
    History.replaceState({myData: data}, null, '?stateHistory=' + uniqueId); 


} 

function manageHistory(url, data, uniqueId){ 
    var History = window.History; 
    if (!History.enabled) { return false; }   
    History.pushState({myData: data}, null, '?stateHistory=' + uniqueId); 


} 

// Event listenner triggering aaa,bbb,ccc 
$('select.select').change(function(e) { 

    e.preventDefault(); 

    // get url 
    // get data 
    // get uniqueId 

    manageHistoryBack(url, data, uniqueId) 


}); 

// Event listenner triggering A, B 
$('select.select').change(function(e) { 

    e.preventDefault(); 

    // get url 
    // get data 
    // get uniqueId 

    manageHistory(url, data, uniqueId) 


}); 


History.Adapter.bind(window, 'statechange', function() { 
    var State = History.getState(); 
    // Launch the ajax call and update DOM using State.data.myData 
}); 

Buona fortuna

Problemi correlati