I have an application that I am trying to create a Greasemonkey script for. It utilizes a lot of jQuery and AJAX to load content dynamically.
I've noticed that the URL does change each time I load a new item, even though the page doesn't refresh.
Is there a listener I can place on the page to relaunch the script each time the URL changes?
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:
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".
Just poll for URL changes. It's simple and works well in practice, with fewer timing issues than all but technique #1.
If the site uses AJAX that changes the fragment (AKA "hash"), fire on the hashchange
event. Alas, fewer and fewer AJAX sites do this.
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.
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.
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With