简体   繁体   中英

HTML5 onpopstate on page load

I'm using the new HTML5 onpopstate event. Using Firefox 4 the window.onpopstate event is triggered on a page load whilst in Webkit this does not seem to be the case.

Which is the correct behaviour?

The popstate event is fired in certain cases when navigating to a session history entry.

http://www.whatwg.org/specs/web-apps/current-work/#event-popstate

From my understanding, though I could be wrong, seeing as loading the page does mean history is created and traversed to, yes, it should be fired on page load.

Also see,

http://www.mail-archive.com/whatwg@lists.whatwg.org/msg19722.html

and,

https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history

Firing onpopstate on page load is correct, and WebKit will have this behavior soon. WebKit 534.7 (Chrome 7.0517.44) now behaves this way.

I filed a Chrome bug on it, but it turns out this is the desired behavior; it is needed in order to handle certain back/forward button actions correctly. See this bug report at code.google.com for more discussion and links.

I'm still trying to come up with a good code pattern for an onpopstate event handler.

I don't know if is this what you are asking, but my solution for an ajax-only onpopstate event handler is to set up to true a variable refreshed on window.onload and set it to false on history.pushState calls; then on the onpopstate handler just do stuff if refreshed is false .

Looks silly, and it is, but I couldn't do any better.

Just solved this issue, and the fix is actually quite simple. Firefox doesn't fire onpopstate on initial page load. After you fire a popstate, return false or prevent default on the page.load action, and you're golden.

Cheers.

In action here: www.thecoffeeshopnyc.com

// Write in a new handler for Firefox, which does not fire popstate on load.
// Modern Webkit browsers fire popstate on load. The event handler below fires the controller
$(window).load(function () {
    if ($.browser.mozilla) {
        // Your func.
    }
})

// Add the event listener. If the above is false, it will still run as intended in normal browsers.
window.onpopstate = function() {
    // Your func.
}

Browsers tend to handle the popstate event differently on page load. Chrome and Safari always emit a popstate event on page load, but Firefox doesn't.

This quote was taken from Mozilla's documentation: https://developer.mozilla.org/en-US/docs/DOM/window.onpopstate

I tend to agree with the Mozilla system. Page load is not an action that requires an extra popstate event to be fired, because the state is not being popped, it is being loaded for the first time.

I am guessing Webkit is doing it for convenience... in all my implementations, it is consistently an inconvenience to delay loading my handler until after the initial popstate has fired.

Instead of this (using pseudo functions):

AddEventHandler(window, 'popstate', OnPopState);

I have to do something like this:

AddLoadEvent(window.setTimeout(function() 
    { 
        AddEventHandler(window, 'popstate', OnPopState); 
    },0));

In case someone is interested, I've came up with a decent pattern for working with onpopstate (this code assumes jQuery, feature detection checks are stripped for clarity):

$(function() {

  // 1. Add initial state to current history record on page load.
  var href = location.href;
  history.replaceState({"href": href}, null, href);

  // 2. Now attach the popstate handler.
  window.onpopstate = function(ev) {

    // Raised on page load this event will still contain no state.
    var state = ev.state;
    if (state && state.href) {

      // 3. Add your logic, use `state` and `state.href` as you see fit.          

    }
  };

});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM