I'm writing a Tampermonkey script and I set up a listener for hashchange
.
Inside that listener, I call a function that manipulates the DOM. The problem is that the function is called before the page is fully loaded.
The page is not completely reloading when switching from one section to another so on load
would only work once, that's why I'm listening for hashchange
instead of load
.
window.addEventListener('hashchange', function (e) {
if (!/step=view&ID=/.test(location.hash)) {
//TODO clean up if leaving active trade
return
}
console.log('hash changed', e)
setup()
});
function setup() {
//wait for page load here
$('.myclass').after(<span>foo</span>);
}
I tried adding on load
inside setup but that did nothing.
Edit:
Adding a listener for load
outside setup
would also work only once if going to the exact link, so that's not an option either.
This is a job for waitForKeyElements
, or MutationObserver
or setTimeout
On almost all such pages, waitForKeyElements by itself is sufficient, no hashchange
listener needed:
// ==UserScript==
// @name _spans of foo
// @match *://YOUR_SERVER.COM/YOUR_PATH/*
// @require https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js
// @require https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant GM_addStyle
// @grant GM.getValue
// ==/UserScript==
//- The @grant directives are needed to restore the proper sandbox.
/* global $, waitForKeyElements */
waitForKeyElements (".myclass", setupMyClass);
function setupMyClass (jNode) {
jNode.after ('<span>foo</span>');
}
Since your added <span>foo</span>
s are apparently not persisting after hashchange, then this technique is probably all you need.
However, if the page is one that reuses the .myclass
nodes (¿but somehow destroys your spans?) instead of recreating them, then use a technique like that shown in this other answer.
In this scenario, MutationObserver might be a better choice. But, that depends on details not provided in your question.
See, also, How do I reload a Greasemonkey script when AJAX changes the URL without reloading the page?.