How do I reload a Greasemonkey script when AJAX changes the URL without reloading the page? How do I reload a Greasemonkey script when AJAX changes the URL without reloading the page? ajax ajax

How do I reload a Greasemonkey script when AJAX changes the URL without reloading the page?


How you do this depends on the site/application and on what you are trying to do. Here are your options, easiest and most robust first:

  1. Don't try to catch URL changes. Use calls to waitForKeyElements() to act on the parts of the various pages that you wanted to manipulate in the first place. This neatly handles a whole slew of timing issues inherent with all the other approaches.
    See also: "Choosing and activating the right controls on an AJAX-driven site".

  2. Just poll for URL changes. It's simple and works well in practice, with fewer timing issues than all but technique #1.

  3. If the site uses AJAX that changes the fragment (AKA "hash"), fire on the hashchange event. Alas, fewer and fewer AJAX sites do this.

  4. Use Mutation Observers to monitor changes to the <title> tag. Most AJAX pages are nice enough to change the title too. This may fire before your target content is loaded, though.

  5. Hack into the history.pushState function. This gives faster notice of page changes, BUT 95% of the time, it fires before your target elements have loaded. You will usually still need a timer. Plus, it brings in cross-scope problems, in a userscript environment.


For reference, here is a polling example. It's still the best, bare-bones, cross-browser, catch-all method:

/*--- Note, gmMain () will fire under all these conditions:    1) The page initially loads or does an HTML reload (F5, etc.).    2) The scheme, host, or port change.  These all cause the browser to       load a fresh page.    3) AJAX changes the URL (even if it does not trigger a new HTML load).*/var fireOnHashChangesToo    = true;var pageURLCheckTimer       = setInterval (    function () {        if (   this.lastPathStr  !== location.pathname            || this.lastQueryStr !== location.search            || (fireOnHashChangesToo && this.lastHashStr !== location.hash)        ) {            this.lastPathStr  = location.pathname;            this.lastQueryStr = location.search;            this.lastHashStr  = location.hash;            gmMain ();        }    }    , 111);function gmMain () {    console.log ('A "New" page has loaded.');    // DO WHATEVER YOU WANT HERE.}


"I've noticed the URL does change each time" with a lot of AJAX would lead me that they are using the History API. If that's the case, take a look at window.onpopstate. That should fire on each URL change using the History API.