改变图像标签的原型?

时间:2013-08-09 17:06:20

标签: javascript dom

我正在尝试编写一个可以执行以下操作的库。

当库包含在头部时,它会改变HTMLImageElement原型,以便用户碰巧在HTML中使用的任何图像标记或者他们在javascript中动态创建的图像标记将具有由我定义的默认的onerror函数库。

这样做的结果是,如果任何用户图片无法加载,因为他们指向了一个糟糕的网址,我的图书馆会以优雅的方式处理它。

我正在尝试以下实验,

var img = document.createElement('img');
  img.__proto__.onerror = function() {
    alert('hi');
  };
  document.body.innerHTML = '<img id="foo" src="bar.png"/>'

文件bar.png不存在且不起作用。

但是,如果我只是做

之类的事情
  document.body.innerHTML = '<img id="foo" src="bar.png" ' +
    'onerror="this.src = MODIT.getImage(\'blackTile\').src;"/>';

工作正常。这里MODIT.getImage()是一个返回图像元素的函数。您可以在此处使用此代码:https://mod.it/ciR_BxqJ/

我正在尝试做什么?或者有没有办法全局捕获所有403 GET错误并以某种方式使用javascript处理它们?

谢谢!

2 个答案:

答案 0 :(得分:5)

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);

请参阅:http://jsfiddle.net/Vudsm/

答案 1 :(得分:2)

重要提示: 弗拉德的解决方案绝对简单!但是,如果要在不使用事件冒泡(将事件侦听器附加到文档)的情况下将事件侦听器附加到任何新添加的元素,请继续阅读。


在阅读了以下问题后,我转而采用完全不同的解决方案。

似乎无法覆盖事件监听器(据我所知,直到现在)。

实际解决方案:DOM突变事件

创建MutationObserver后,会监听添加的节点,然后检查它们是否为图像,并动态添加错误处理程序。

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"/>'

您还可以使用IE 9也支持的 DOMNodeInserted事件:

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"/>'