问题
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