javascriptpushstatehistory.js

History.js window.onstatechange doesn't fire


I'm just a js beginner, so maybe I just don't understand it right. But isn't the window.onstatechange supposed to fire when you hit the back/forward button of your browser when you previously changed the state with History.stateObj ?

I actually see the object changing in the Firebug console, but window.onstatechange just won't fire! Also - very confusing - when I use window.onpopstate instead, the object isn't changing anymore (when using the back/forward button).

Here's what I do:

$('.container').click(function(e) {
        e.preventDefault();
        var title = $(this).data('title');
        stateObj = { show: title }
        History.pushState(stateObj, document.title, '?show=' + title);
}

window.onstatechange = function() {     
            var title = History.getState().data['show'];
            alert('title');
}

I already found out from here, that I have to use

History.Adapter.bind(window,'statechange',function(){
            var title = History.getState().data['show'];
            alert('title');

});

...which works, but I still don't really understand why window.onstatechange won't fire?!

// EDIT: Opened a ticket on Github

Any suggestions ?


Solution

  • Lucian Poston answered this question on GitHub in April 2012:

    This seems to be the design of the History.Adapter event model. Have a look at the adapters' implementations e.g. https://github.com/balupton/history.js/blob/master/scripts/uncompressed/history.adapter.native.js

    When history.js raises a 'statechange' event, it invokes History.Adapter.trigger(), which iterates over a list of event handlers setup via prior calls to History.Adapter.bind(). window.onstatechange() is not invoked as you expected.

    Actually, History.Adapter.bind(window, 'statechange', function(){ alert('oi'); }) sets up window.onstatechange so that if fired, it would invoke History.Adapter.trigger(window, 'statechange'), which in turn would invoke the event handler, function(){ alert('oi'); }. If you redefine window.onstatechange as in your example, it would break that behavior.