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

1、简介

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

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

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

HTML

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,这一点跟其它浏览器一致;

IE下img标签error事件的兼容性问题_第1张图片
图2-1 IE·不传参

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

IE下img标签error事件的兼容性问题_第2张图片
图2-2 IE·传参

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

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

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

HTML

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的过程中,被废弃的那些图片地址都显示挂起,应该是被中断掉了。

IE下img标签error事件的兼容性问题_第3张图片
图2-3 IE·“多次变更src”的网络请求

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

IE下img标签error事件的兼容性问题_第4张图片
图2-4 Chrome·“多次变更src”的网络请求(Opera、FireFox相同)

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

IE下img标签error事件的兼容性问题_第5张图片
图2-5 Safari·“多次变更src”的网络请求

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

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

IE下img标签error事件的兼容性问题_第6张图片
图2-6 IE·无src传参

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

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

使用onload的代码为:

// 初始将图片隐藏

img{display:none;}

// 此处有无src均可

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

3、结论

解决问题的办法有两个:

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

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

你可能感兴趣的:(IE下img标签error事件的兼容性问题)