9

为什么其他浏览器(IE7、8、9、FF、Opera、Safari)都重复调用img元素的onerror事件,Chrome只调用一次?

有没有办法强制它再次重复 onerror 调用(在 Chrome 中)?

jsfiddle

HTML:

<div id="thisWorks">
    this works in Chrome. onerror event is called once.
    <img src="http://www.asdfjklasdfasdf.com/bogus1.png" 
        onerror="fixit(this);" 
        rsrc="http://eatfrenzy.com/images/success-tick.png" />
</div>

<div id="thisDoesNotWork">
    this does not work in Chrome. onerror event is not called twice.
    <img src="http://www.asdfjklasdfasdf.com/bogus1.png" 
        onerror="fixit(this);"
        rsrc="http://www.asdfjklasdfasdf.com/bogus2.png|http://eatfrenzy.com/images/success-tick.png" />
</div>

JAVASCRIPT:

function fixit(img)
{
    var arrPhotos = img.getAttribute('rsrc').split('|');

    // change the img src to the next available
    img.setAttribute('src', arrPhotos.shift());

    // now put back the image list (with one less) into the rsrc attr
    img.setAttribute('rsrc', arrPhotos.join('|'));

    return true;    
}

编辑: 根据@Sunil D.关于 Chromewww.asdfjklasdfasdf.com最初的小提琴示例中由于域名无效而不发出新查找的评论,我继续更改域名以匹配成功图像的域名,但使用不同的文件名所以它仍然是 404。这将证明它不是导致 Chrome 在第二次尝试中退出的无效域名。

编辑: 更新了小提琴并删除了对 jquery 的使用,以简单地排除这种情况。

4

5 回答 5

5

好,知道了。在分配给 onerror 事件的函数中,src属性设置为,null然后再将其更改为新值

img.setAttribute('src', null);

工作小提琴

这会以某种方式导致 Chrome 重置它,如果后续值src返回错误,它将强制它重复调用 onerror。

注意:空字符串不起作用,必须是null.
注意 2:此修复程序使用纯 javascript(但不适用于 jquery.attr方法)。发布此解决方案后,我尝试使用 jquery.attr方法将其设置为,$img.attr('src', null);但它没有那样工作,当我将其更改为 javascript 时,它工作了。我也尝试使用 jquery.prop方法,而不是像$img.prop('src', null);第一次那样工作,但在随后的几次刷新中失败了。只有纯 javascript 似乎是一个万无一失的解决方案。

更新:
好的,事实证明,虽然上述更改修复了 Chrome 并导致它像所有其他浏览器(FF、Safari、Opera、IE7-9)一样重复调用 onerror,但它会导致 IE10 的 onerror 事件出现问题,因此忽略任何src将其设置为=null上一行后分配给的有效图像。(...叹)。

于 2013-07-14T05:46:06.367 回答
5

我试过上面提到的方法, setAttribute('src', null) 有一个副作用,即添加另一个请求。

最后,我使用

    setTimeout(function(){ imgElement.src = 'http://xxxx'; }, 0)

,这行得通!

例如,请参阅jsfiddle

于 2013-07-15T14:26:16.167 回答
0

这是正确的行为。你不想两次下载同一个图像——那是对带宽的浪费。

Chrome 会创建一个内存对象,然后将其应用于所有具有相应src.

如果您需要下载两次,然后通过 javascript 创建这些对象并分配.onload=function() { .. }给每个对象。

于 2013-07-14T04:02:58.797 回答
0

我认为@Mikhail 是在正确的轨道上,除了稍微不同的原因。在第二个示例中,您尝试从同一个不存在的域下载 2 个图像www.asdfjklasdfasdf.com

尝试下载bogus1.png时,Chrome 无法将域解析为 IP 地址。

当尝试下载bogus2.png(从同一个不存在的域)时,Chrome 根本不做任何事情......因为它知道域查找失败。chrome 不发送另一个onerror事件是否是正确的行为可能会引起争论:) 我有点希望它应该这样做。

为了证明这一点,只需在域名中添加 1 个字符,bogus2.png它就会按您的预期工作。

编辑

您可以强制它尝试后续下载的一种方法是将 的 更改为src<img>字符串。这有点hacky,但它有效。您可以将rsrc属性设置为如下所示:

rsrc="''|http://www.asdfjklasdfasdf.com/bogus2.png|''|http://eatfrenzy.com/images/success-tick.png"

这样,当错误发生时,您将源设置为''。这似乎也会产生一个错误,然后触发它尝试下一个来源......

于 2013-07-14T04:16:35.130 回答
0

正如 Etdashou 在这个问题上的回答:https ://stackoverflow.com/a/9891041/1090274 ,设置this.onerror=null;对我有用。

于 2015-03-31T15:25:12.190 回答