问题
From my homepage, let's call it
mysite.com
, I click a link which has thishref
value:/home/home.php?doc=gym
. So, the entire url ismysite.com/home/home.php?doc=gym#
(The browser adds the#
at the end of the url, but I need that to be before the parameters in order the plugin works fine).From that page,
home.php
, I clicked a link that I caught its event, load some Ajax data and want to change the urlmysite.com/home/home.php?doc=gym
tomysite.com/home/home.php?doc=pilates
. So, what I do is: as soon as the content is loaded, I executeHistory.pushState(null, null, url);
where url =?doc=pilates
.Here is when the problem comes, in Internet Explorer 8, for example, the new url is:
mysite.com/home/home.php?doc=gym#home.php?doc=pilates
instead ofmysite.com/home/home.php?doc=pilates
.And this happens, I suppose, because of the last thing I said in step
1.
If I click another link and execute the
pushState
method, it replaces the?doc=pilates
with the parameters I wrote as a third parameter of the function, because it's after the#
symbol.
回答1:
Some code examples would be nice but from your explanation i get the idea you are not implementing history.js correctly.
You have to push state in the href click event then catch the statechange
event and do your ajax loading and dom manipulation there.
You have to use it like that because the statechange
event fires when you call the pushState
function.
EDIT by Shikyo:
So, what I do is: as soon as the content is loaded, I execute History.pushState(null, null, url);
That is why i got the idea you are not using it correctly. You have to pushState
then in the statechange
event load your content and update the dom. Not update the dom first then call pushState
.
As for the initial state in html4 browsers the history.js plugin does never fire a initial state change event.
I found 2 solutions for taking care of the initial state in html 4 browsers:
1) Call History.getState()
in a document ready event and take care of the initial state.
2) Trigger the statechange event yourself:
// If pushState is emulated (html4 browsers) and we have a hash (a '#' in the url) trigger the statechange event
if (History.emulated.pushState && History.getHash())
{
$(document).ready(function()
{
History.Adapter.trigger(window, "statechange");
});
}
And of course handle any DOM manipulated inside the statechange
event.
EDIT 2 by ksairi:
As an update, I think that as I'm loading ajax content it does not matter when I load and when I change the url, becuase the loading of the content does not affect the url nor the pushstate affect the loading. Maybe there is something I am not understanding.
Actually part of the code from the demo is the following:
(function(window,undefined){
var
History = window.History,
State = History.getState(),
$log = $('#log');
// Log Initial State
History.log('initial:', State.data, State.title, State.url);
// Bind to State Change
History.Adapter.bind(window,'statechange',function(){ // Note: We are using statechange instead of popstate
// Log the State
var State = History.getState(); // Note: We are using History.getState() instead of event.state
History.log('statechange:', State.data, State.title, State.url);
});
})(window);
As you can see, History.getState() is executed and I tested that in IE8.
In html5 browsers, when you land to a page, it doesn't execute the statechange, it does do it when you pushstate. In both, html4 and html5 browsers.
EDIT 3 by Shikyo:
Ok this is why you need to do something special in html4 browsers for the initial state:
In html5 browsers the actual url gets changed, for example from http://mysite.com/
to http://mysite.com/page/1
in html4 the url gets changed to http://mysite.com/#page=1
Note that the url is not actually changed, only the bit after the #
which is called a hash is changed.
The server does not know what comes behind the hash so in html5 browsers the servers loads http://mysite.com/page/1
and in html4 browsers everything after the #
is ignored by the server so the url is http://mysite.com/
.
In html5 browsers the correct content gets loaded because the url points to the right address. In html4 browsers you have to take care of the initial state manually because the content is not loaded the first time and the statechange
event is not triggered.
See my first edit for possible solutions to this problem.
回答2:
Shikyo, I did what you told to me to and it actually helped me, the back and foward buttons show the correct content now. Thank you for that, I did not think of the behaviour of those. Unfortunately, the problem persists in html4 browsers. The page is galagym.com/home/home.php. You can enter to the different sections on the left and look the wrong behaviour of the url, of course in a html4 browser. In html5 browser it workes perfectly.
So if you/anyone can give me notes, it would be great.
thanks!
来源:https://stackoverflow.com/questions/12681699/jquery-plugin-history-js-not-working-properly-in-html4-browsers