How to Get Notified About Changes of the History via History.Pushstate

How to get notified about changes of the history via history.pushState?

5.5.9.1 Event definitions

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

According to this, there is no reason for popstate to be fired when you use pushState. But an event such as pushstate would come in handy. Because history is a host object, you should be careful with it, but Firefox seems to be nice in this case. This code works just fine:

(function(history){
var pushState = history.pushState;
history.pushState = function(state) {
if (typeof history.onpushstate == "function") {
history.onpushstate({state: state});
}
// ... whatever else you want to do
// maybe call onhashchange e.handler
return pushState.apply(history, arguments);
};
})(window.history);

Your jsfiddle becomes:

window.onpopstate = history.onpushstate = function(e) { ... }

You can monkey-patch window.history.replaceState in the same way.

Note: of course you can add onpushstate simply to the global object, and you can even make it handle more events via add/removeListener

How to detect when history.pushState and history.replaceState are used?

The onpopstate event should be fired when the history changes, you can bind to it in your code like this:

window.onpopstate = function (event) {
// do stuff here
}

This event may also be fired when the page loads, you can determine whether the event was fired from a page load, or by using pushState/replaceState by checking the event object for a state property, it will be undefined if the event was caused by a page load

window.onpopstate = function (event) {
if (event.state) {
// history changed because of pushState/replaceState
} else {
// history changed because of a page load
}
}

There currently is no onpushstate event unfortunately, to get around this you need to wrap both the pushState and replaceState methods to implement your own onpushstate event.

I have a library that makes working with pushState a bit easier, it might be worth checking it out called Davis.js, it provides a simple api for working with routing based on pushState.

Is there a callback for History.pushstate?

No, there's not a onpushstate or whatever. However, a little monkey patching can fix that:

var pushState = history.pushState;
history.pushState = function () {
pushState.apply(history, arguments);
fireEvents('pushState', arguments); // Some event-handling function
};

This will only notify you when pushState is used. You'd probably want to do something similar for replaceState.

If you need to be notified whenever the URL changes at all, some combination of the above and a hashchange handler will get you most of the way there.

YouTube not triggering history.pushState

YouTube uses spfjs to manipulate pushState. However it grabs the function generally before you can monkey patch it. This is why you are experiencing the issue.

Either move your monkey patch script up in the page before spf.js is loaded, or you can look for the spf events like spfdone to detect the change.

monitoring history.pushstate from a chrome extension

Yes,

One way is to create a script tag and put your code there:

html = "window.history.pushState = function(a,b,c) { alert('Change !'); };";

var headID = document.getElementsByTagName("head")[0];
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.innerHTML = html;
headID.appendChild(newScript);


Related Topics



Leave a reply



Submit