美文网首页
IE下img标签error事件的兼容性问题

IE下img标签error事件的兼容性问题

作者: 半吊子伯爵 | 来源:发表于2017-11-27 14:13 被阅读0次

1、简介

现需在一个html页面中显示一张图片,这张图片的地址是通过GET方式从地址栏中传入的。但是如果图片损坏或传参错误,在部分浏览器下会出现破裂图,所以当遇到这种情况则将图片隐藏掉。

地址示例:http://example.com/test.html?s=1.jpg

据此要求编写的初始代码如下(代码中的两个console用于后续的测试):

HTML

<img src="" id="image" onerror="this.onerror='';console.log('none');this.style.display='none'">

JS

var imgSrc=GetUrlParams().s||"";   // GetUrlParams是用来获取url中的参数的,参数名为s

var img=document.getElementById("image");

if (imgSrc) {

    img.src=imgSrc+"?t="+Math.random();

    console.log('block');

    img.style.display='block';

}

2、问题

当用上述代码在各浏览器中进行测试时,发现在IE下图片无法显示,但从开发者工具中可以看到图片是正确请求了。其它浏览器(Chrome、Opera、FireFox、Safari)表现符合预期。

之后我对IE做了一些测试,测试内容如下:

1)当不传参数时,img的error事件会被触发,控制台输出none,这一点跟其它浏览器一致;

图2-1 IE·不传参

2)当传参时,其它浏览器均不触发error事件,只有IE会触发;

图2-2 IE·传参

按照浏览器的加载原则,图片会在其它所有代码之后加载,所以页面先获取到了图片地址参数并更新到了img标签上,然后才去加载图片。也就是说,当加载图片时,图片的地址已经是最终的那个传参了,理论上是不应该触发error事件的。

IE这个行为比较奇怪。经过一番琢磨后,我猜想IE是不是在自上而下读到img标签处时,虽然没立即加载图片,但是却把图片的地址添加到了后续的计划任务中,就好像打印机那样,然后在其它代码加载完之后陆续请求了这些地址(就像是请求了一个地址数组[“”,”1.jpg”])。为了验证这一猜想,我做了如下的一番测试:

① 编写了一个新的页面,功能是在初始化时,通过循环多次修改img的src属性,然后观察IE是否会对所有赋值都发起请求。

HTML

<img id="image" onload="this.style.display='block'">

JS

var img=document.getElementById("image");

var imgArr=["1.jpg","favicon.png","loading.gif"];

for (var i = 0; i < imgArr.length; i++) {img.src=imgArr[i]+"?t="+Math.random();}

测试后发现,IE的确请求了数组中所有的地址,但在变更img的src的过程中,被废弃的那些图片地址都显示挂起,应该是被中断掉了。

图2-3 IE·“多次变更src”的网络请求

② 继续观察该测试页面在其它浏览器下的反应,发现Chrome、FireFox、Opera均只请求了最后那张图片的地址。

图2-4 Chrome·“多次变更src”的网络请求(Opera、FireFox相同)

但是Safari的表现有点意外了,它像IE一样请求了所有的地址,不过在开发者工具界面上的显示与IE略有不同。

图2-5 Safari·“多次变更src”的网络请求

3)根据上面的测试,我将img标签的src属性从html中去除掉,代码成了:

<img id="image" onerror="this.onerror='';console.log('none');this.style.display='none'">

然后再进行测试,发现IE不再触发img的error事件,可以解决图片不显示的问题。 

图2-6 IE·无src传参

之后,我又测试了将src赋值为“javascript:;”,发现也不会在IE下触发img的error事件,其它部分浏览器(如Safari)虽然控制台可能会报错,但并不影响页面功能。

4)虽然本次实验是因为onerror而起,但就功能而言,其实用onload事件会更加容易实现和理解(各个浏览器表现一致)。只是最初入门前端时见到的是onerror这样的错误处理方法,往后就优先想到它,而没再往其它方向考虑。

使用onload的代码为:

// 初始将图片隐藏

img{display:none;}

// 此处有无src均可

<img id="image" onload="this.style.display='block'">

附:最早见过的印象深刻的onerror用法

<img src=”main.png” onerror=” this.onerror=''; this.src=’default.png’”>

3、结论

解决问题的办法有两个:

1)将img标签的src属性不写或者写成正确但无意义的值(如src="javascript:;")。

<img id="image" onerror="this.onerror=''; this.style.display='none'">

<img src="javascript:;" id="image" onerror="this.onerror=''; this.style.display='none'">

2)使用onload代替onerror事件实现上文所述的功能。

<img id="image" onload="this.style.display='block'">

相关文章

网友评论

      本文标题:IE下img标签error事件的兼容性问题

      本文链接:https://www.haomeiwen.com/subject/bkosbxtx.html