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 image tag that the user happened to use in their HTML or that they create dynamically in javascript would have a default onerror function that is defined by my library.
The result of this would be that if any of the users images failed to load because they pointed to a bad url my library would handle it in a graceful way.
I am trying the following just as an experiment,
var img = document.createElement('img');
img.__proto__.onerror = function() {
alert('hi');
};
document.body.innerHTML = '<img id="foo" src="bar.png"/>'
where the file bar.png does not exist and it does not work.
However if I just do something like
document.body.innerHTML = '<img id="foo" src="bar.png" ' +
'onerror="this.src = MODIT.getImage(\'blackTile\').src;"/>';
that works fine. Here MODIT.getImage() is a function that returns an image element. You can play with this code here: https://mod.it/ciR_BxqJ/
Is what I'm trying to do possible? Alternatively is there a way to globally catch all 403 GET errors and handle them with javascript in some way?
Thanks!
The prototype of an object is referred to by the prototype property of the constructor function that creates and initializes the object. The isPrototypeOf() method provides a way to determine if one object is the prototype of another. This technique can be used to determine the class of an object.
In JavaScript, every function and object has a property named prototype by default. For example, function Person () { this.name = 'John', this. age = 23 } const person = new Person(); // checking the prototype value console.
A prototype is an existing inbuilt functionality in JavaScript. Whenever we create a JavaScript function, JavaScript adds a prototype property to that function. A prototype is an object, where it can add new variables and methods to the existing object.
Prototype is a JavaScript framework that aims to ease development of dynamic web applications. It offers a familiar class-style OO framework, extensive Ajax support, higher-order programming constructs, and easy DOM manipulation.
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"/>'
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