In a browser scope, a globalEventHandler or eventListeners would be the way to go.
But because userscripts have some differents scopes for window
and document
, it does not work as it is. This scoping problem is the same using web extensions (next gen userscipts..), but at least it force us to much take care of the DOM.
Here is some workarounds for userscripts, following own experiments.
Usually my experiments leads to downvotes by incurious «programmers», so no worries and have fun!
First instead of load events, inside the usercript, loading scripts with a delay. It is dirty but help a lot, at least for debugging.
setTimeout(function(){ }, 3000)
To load event handlers into the main document, we got to create an element and append it to the main DOM.
In most cases, issues comes just because browsers loads local resources much faster, we must specify where the script should be on the target page, or it may be positioned at the very top of the DOM. (Meaning no event handler, we can't call id by their name, we would need to use getElementById, etc,etc)
s = document.createElement("script")
s.innerText = "" // The events scripts
document.body.appendChild(s)
The good point here, the script can be external. By loading external scripts, browsers will take care to append it to the DOM, actually if the DOM is well loaded. in most cases stuffs start to works with just this action.
An other alternative is to directly set a onchange
attribute on each element of the target DOM.
This is valid, if the elements already exists. (If you are loading your images by changing the src). You can as well set many (hidden) element as need for later and set their attribute. This is a bit redundant, but avoid any event listeners. It is flat approach. It can be done server side too.
To set an onchange on all images tags, without knowing their id, we can use querySelectorAll
, which is on this case very useful because we can use forEach
on it. (Unlike getElementsBytagName
)
document.querySelectorAll("img").forEach(function(element){
element.setAttribute("onchange","handleImgTag()")
})
Now all together:
setTimeout(function(){
// the querySelectorAll function encoded in base64
var all = "ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnaW1nJykuZm9yRWFjaChmdW5jdGlvbihlbGVtZW50KXsNCiAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ29ubG9hZCcsJ2FsZXJ0KCknKQ0KfSk="
s = document.createElement("script")
// The events scripts, base64 decoded
s.innerText = atob(all) + ""
document.body.appendChild(s) // End of DOM, at trigger.
}, 1000) // Onloads sets after 1s.
<img src="http://icons.iconarchive.com/icons/martin-berube/flat-animal/64/pony-icon.png"></img>
<img src="" id="more"></img>
<button onclick="more.src='http://icons.iconarchive.com/icons/martin-berube/flat-animal/64/crab-icon.png'">LOAD MORE</button>
Scoping is the key for good userscripts.
Try to put all your script at the DOM end. Good luck!