Search code examples
javascripteventsmutation-observers

How to observe a change in the URL using JavaScript?


The documentation for the popstate Window event states:

Note that just calling history.pushState() or history.replaceState() won't trigger a popstate event. The popstate event will be triggered by doing a browser action such as a click on the back or forward button (or calling history.back() or history.forward() in JavaScript).

I need a way to execute some code when the URL changes by means that don't trigger the popstate event (such as history.replaceState()). Preferably, using the MutationObserver API[1], and most definitely without polling the URL every x seconds.

Also, hashchange won't do, as I must act on every change in the URL, not just the hash part.

Is that possible?


[1] It is explained on another question why the MutationObserver API doesn't work for this.


(other) Related questions:


Solution

  • You need to redefine (wrap) the history.replaceState that the other script is using:

    (function(){
      var rs = history.replaceState; 
      history.replaceState = function(){
        rs.apply(history, arguments); // preserve normal functionality
        console.log("navigating", arguments); // do something extra here; raise an event
      };
    }());
    

    No polling, no waste, no re-writing, no hassle.

    Do the same for pushState, or whatever other natives (like ajax) you wish/need when writing userscripts.