I am trying to write a library that would do the following.
When the library is included in the head, it would alter the HTMLImageElement prototype such that any ima
window.addEventListener("error", function(e) {
if ( e && e.target && e.target.nodeName && e.target.nodeName.toLowerCase() == "img" ) {
alert( 'Bad image src: ' + e.target.src);
}
}, true);
See: http://jsfiddle.net/Vudsm/
Important note: Vlad's solution is definitely simpler! But if you want to attach an event listener to any newly added element without using event bubbling (attaching event listeners to the document), read on.
After reading the following questions, I switched to a completely different solution.
Modify prototypes of every possible DOM element
JavaScript: override Date.prototype.constructor
It seems that one cannot override an event listener (as far as I have researched until now).
The actual solution: DOM mutation events
After creating a MutationObserver, one listens for added nodes, then checks whether they are images and one dynamically adds an error handler.
jsFiddle
function imgError() {
alert("Failed to load image!");
}
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var config = {
childList: true
};
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
var addedNodesCount = mutation.addedNodes.length;
for (var i=0; i<addedNodesCount; i++) {
var node = mutation.addedNodes.item(i);
if (node.tagName == "IMG") {
node.addEventListener("error", imgError);
}
}
});
});
// pass in the target node, as well as the observer options
observer.observe(document.body, config);
document.body.innerHTML = '<img id="foo" src="bar.png"/>'
You can also use the old DOMNodeInserted
event which is also supported by IE 9:
jsFiddle
function imgError() {
alert("Failed to load image!");
}
document.body.addEventListener("DOMNodeInserted", function (evt) {
if (evt.target.tagName == "IMG") {
evt.target.addEventListener("error", imgError);
}
});
document.body.innerHTML = '<img id="foo" src="bar.png"/>'