jquery plugin history.js not working properly in h

2019-07-30 19:20发布

  1. From my homepage, let's call it mysite.com, I click a link which has this href value: /home/home.php?doc=gym. So, the entire url is mysite.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).

  2. From that page, home.php, I clicked a link that I caught its event, load some Ajax data and want to change the url mysite.com/home/home.php?doc=gym to mysite.com/home/home.php?doc=pilates. So, what I do is: as soon as the content is loaded, I execute History.pushState(null, null, url); where url = ?doc=pilates.

  3. 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 of mysite.com/home/home.php?doc=pilates.

  4. And this happens, I suppose, because of the last thing I said in step 1.

  5. 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.

2条回答
等我变得足够好
2楼-- · 2019-07-30 19:33

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.

查看更多
霸刀☆藐视天下
3楼-- · 2019-07-30 19:45

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!

查看更多
登录 后发表回答