browser back and forward button does not invoke callback method with statechange event of history.js

穿精又带淫゛_ 提交于 2019-12-18 05:06:06

问题


I used (https://github.com/browserstate/history.js) and have a piece of code like this

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);
}

if I invoke manageHistory() after my ajax call, then History.Adapter.bind callback method get invoked correctly. However, if I click the browser back and then click forward button that result in page navigation from B to A, then A back to B, call back method inside History.Adapter.bind does not get invoked. This happen on both chrome and IE9. Anyone know how to fix this issue, I need to get the State after click browser back and then forward, to update my DOM. Please help

Note: I use version 1.7.1 jquery.history.js for html4 browser IE9

UPDATE (May 3 2013): Talk a bit more about my requirement

Sorry I was busy with other task, that not until now that I have sometimes to look at this issue. So oncomplete of an ajax call, I took that information that return to me, and push it into state. My requirement is: that if I navigate from page A to page B, and then on page B, I execute numbers of ajax requests that result in DOM manipulation (let call each ajax request that result in DOM manipulation a state). If I click the back button, I should go back to page A, and if I click the forward button, I should go to page B with the last state that I was in.

So my thought was, oncomplete of my ajax request, I would replace the last state in history with my current state (my json object is the html that I receive back from the ajax request). If I use push state, let say I am on page B, and I click one button, my page now change to aaa, I pushState aaa. Then if I click other button, my page now change to bbb, I pushState bbb. If I click the back button now, I would still be on page B, with my state in History.Adapter.bind(window, 'statechange', function() {}) show as aaa, if I click back button again, i would go to page A. I do not want this behavior. I want that if I am on page B with state bbb, and click back, I would go to page A, and if I click forward, I would go to page B with state bbb. I hope this make more sense. Please help


回答1:


What you need to do is as follows:

  • If the page you came from is another page (e.g. you open page B and the previous page was page A) you do a pushState.
  • If on the other hand the previous page was the same page as you're currently on you will simply do a replaceState, replacing the information with information about your current state.

(the tracking of the previous page you will need to do manually in some variable)

This means that if you go from A to B (pushState) to new state of B (replaceState), back button (goes to state info of A) and next forward (goes to the newest state of B). Additionally if you open A the first time you need to do a replaceState with information about the state of A so that A will have some state at least (otherwise it will have an empty data object).

It might be useful to look at this answer of mine, which is simply about the way you would built an ordered history stack with pushStates. Not exactly what you want of course, but it's a bit simpler written and together with the information in this answer it should get you the behaviour you want.




回答2:


I see that you are using History.replaceState which remove the last history state in the stack and replace it by the state given in parameters.

I am using History.pushState in my website, and doesn't face such an issue because this function doesnt pull the last state but add the new state above it. It is making the back-forward buttons work correcly.

I hope it helps you.

Edit: Using the example of change of select tag as event listenner:

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
});



回答3:


Also,

relpaceState will always erase B state.

Use pushState for A and B states.

And use replacestate for aaa, bbb, ccc states.

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 
});

Good luck



来源:https://stackoverflow.com/questions/16164210/browser-back-and-forward-button-does-not-invoke-callback-method-with-statechange

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!