How To Overwrite Addeventlistener In Firefox 3.x?
Solution 1:
That's quite bad what they did there... Luckily they fixed it since then ;-)
var el1 = document.createElement('div');
var el2 = document.createElement('div');
el1.addEventListener === el2.addEventListener;
is false
in FF 3.2...
This means that they were setting for every element its own version of the function (probably a bound version).
Given this, your only way is to catch all the elements and append to them your own version one by one.
One way is to overwrite the document.createElement
method, but this will work only on elements that are created by scripts.
To catch the ones that in the markup, you could use a TreeWalker.
functionoverwrite(target) {
if (target._addEvent_overwritten) return; // do it only once// calling the Element.prototype.addEventListener throws an Error in FF3.xvar prevAddEventListener = target.addEventListener;
target.addEventListener = function(type, handler, options) {
prevAddEventListener.call(this, type, handler, !!options);
};
target._addEvent_overwritten = true;
}
// catch in document.createElement // FF 3.x doesn't set the Document.prototype.createElementvar prevCreateElem = HTMLDocument.prototype.createElement;
HTMLDocument.prototype.createElement = function(type) {
var elem = prevCreateElem.call(this, type);
overwrite(elem);
return elem;
};
// not only Elements do have this method...overwrite(window);
overwrite(document);
// catch after Document has been generateddocument.addEventListener('DOMContentLoaded', function() {
// catch all Elementsvar walker = document.createTreeWalker(
document.documentElement, NodeFilter.SHOW_ELEMENT, null, false
);
while (walker.nextNode())
overwrite(walker.currentNode);
});
// Testsvar elem = document.createElement('div');
elem.addEventListener('click', function(evt) {
this.textContent = 'clicked'
});
elem.textContent = 'click me (dynamic)';
document.body.appendChild(elem);
window.addEventListener('load', function() {
document.getElementById('in-doc').addEventListener('click', function() {
this.textContent = 'clicked';
});
});
<divid="in-doc">click me (in markup)</div>
However this won't catch the ones in markup that receive event listeners before the DOMContentLoaded event fired.
For these, you will probably have to also overwrite all of document.getElementById
, document.querySelector
, Element_instance.querySelector
, NodeList
getters, HTMLCollection
getters etc.
That's not a trivial task, and I unfortunately miss the incentives to do it all for this answer, since I only use this FF version from mozregression when searching about a bug, but at least you get the idea.
Solution 2:
addEventListener
is inherited from the EventTarget
prototype, not Element
.
var placeToReplace;
if (window.EventTarget && EventTarget.prototype.addEventListener) {
placeToReplace = EventTarget;
} else {
placeToReplace = Element;
}
placeToReplace.prototype.oldaddEventListener = placeToReplace.prototype.addEventListener;
placeToReplace.prototype.addEventListener = function(event, handler, placeholder) {
console.log("calling substitute");
if (arguments.length < 3) {
this.oldaddEventListener(event, handler, false);
} else {
this.oldaddEventListener(event, handler, placeholder);
}
}
document.querySelector("div").addEventListener("click", function() {
console.log("foo");
});
<div>Click me</div>
Post a Comment for "How To Overwrite Addeventlistener In Firefox 3.x?"