IE下img標(biāo)簽error事件的兼容性問題

1、簡(jiǎn)介

現(xiàn)需在一個(gè)html頁面中顯示一張圖片,這張圖片的地址是通過GET方式從地址欄中傳入的。但是如果圖片損壞或傳參錯(cuò)誤,在部分瀏覽器下會(huì)出現(xiàn)破裂圖,所以當(dāng)遇到這種情況則將圖片隱藏掉。

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

據(jù)此要求編寫的初始代碼如下(代碼中的兩個(gè)console用于后續(xù)的測(cè)試):

HTML

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

JS

var imgSrc=GetUrlParams().s||"";? ?// GetUrlParams是用來獲取url中的參數(shù)的,參數(shù)名為s

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

if (imgSrc) {

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

????console.log('block');

????img.style.display='block';

}

2、問題

當(dāng)用上述代碼在各瀏覽器中進(jìn)行測(cè)試時(shí),發(fā)現(xiàn)在IE下圖片無法顯示,但從開發(fā)者工具中可以看到圖片是正確請(qǐng)求了。其它瀏覽器(Chrome、Opera、FireFox、Safari)表現(xiàn)符合預(yù)期。

之后我對(duì)IE做了一些測(cè)試,測(cè)試內(nèi)容如下:

1)當(dāng)不傳參數(shù)時(shí),img的error事件會(huì)被觸發(fā),控制臺(tái)輸出none,這一點(diǎn)跟其它瀏覽器一致;

圖2-1 IE·不傳參

2)當(dāng)傳參時(shí),其它瀏覽器均不觸發(fā)error事件,只有IE會(huì)觸發(fā);

圖2-2 IE·傳參

按照瀏覽器的加載原則,圖片會(huì)在其它所有代碼之后加載,所以頁面先獲取到了圖片地址參數(shù)并更新到了img標(biāo)簽上,然后才去加載圖片。也就是說,當(dāng)加載圖片時(shí),圖片的地址已經(jīng)是最終的那個(gè)傳參了,理論上是不應(yīng)該觸發(fā)error事件的。

IE這個(gè)行為比較奇怪。經(jīng)過一番琢磨后,我猜想IE是不是在自上而下讀到img標(biāo)簽處時(shí),雖然沒立即加載圖片,但是卻把圖片的地址添加到了后續(xù)的計(jì)劃任務(wù)中,就好像打印機(jī)那樣,然后在其它代碼加載完之后陸續(xù)請(qǐng)求了這些地址(就像是請(qǐng)求了一個(gè)地址數(shù)組[“”,”1.jpg”])。為了驗(yàn)證這一猜想,我做了如下的一番測(cè)試:

① 編寫了一個(gè)新的頁面,功能是在初始化時(shí),通過循環(huán)多次修改img的src屬性,然后觀察IE是否會(huì)對(duì)所有賦值都發(fā)起請(qǐng)求。

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

測(cè)試后發(fā)現(xiàn),IE的確請(qǐng)求了數(shù)組中所有的地址,但在變更img的src的過程中,被廢棄的那些圖片地址都顯示掛起,應(yīng)該是被中斷掉了。

圖2-3 IE·“多次變更src”的網(wǎng)絡(luò)請(qǐng)求

② 繼續(xù)觀察該測(cè)試頁面在其它瀏覽器下的反應(yīng),發(fā)現(xiàn)Chrome、FireFox、Opera均只請(qǐng)求了最后那張圖片的地址。

圖2-4 Chrome·“多次變更src”的網(wǎng)絡(luò)請(qǐng)求(Opera、FireFox相同)

但是Safari的表現(xiàn)有點(diǎn)意外了,它像IE一樣請(qǐng)求了所有的地址,不過在開發(fā)者工具界面上的顯示與IE略有不同。

圖2-5 Safari·“多次變更src”的網(wǎng)絡(luò)請(qǐng)求

3)根據(jù)上面的測(cè)試,我將img標(biāo)簽的src屬性從html中去除掉,代碼成了:

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

然后再進(jìn)行測(cè)試,發(fā)現(xiàn)IE不再觸發(fā)img的error事件,可以解決圖片不顯示的問題。?

圖2-6 IE·無src傳參

之后,我又測(cè)試了將src賦值為“javascript:;”,發(fā)現(xiàn)也不會(huì)在IE下觸發(fā)img的error事件,其它部分瀏覽器(如Safari)雖然控制臺(tái)可能會(huì)報(bào)錯(cuò),但并不影響頁面功能。

4)雖然本次實(shí)驗(yàn)是因?yàn)閛nerror而起,但就功能而言,其實(shí)用onload事件會(huì)更加容易實(shí)現(xiàn)和理解(各個(gè)瀏覽器表現(xiàn)一致)。只是最初入門前端時(shí)見到的是onerror這樣的錯(cuò)誤處理方法,往后就優(yōu)先想到它,而沒再往其它方向考慮。

使用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、結(jié)論

解決問題的辦法有兩個(gè):

1)將img標(biāo)簽的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事件實(shí)現(xiàn)上文所述的功能。

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.使用meta標(biāo)簽調(diào)節(jié)瀏覽器的渲染方式,告訴瀏覽器用哪種內(nèi)核渲染,360雙核瀏覽器就是在ie和chrome之間來...
    不去解釋閱讀 427評(píng)論 0 1
  • 隨著手機(jī)的普及,移動(dòng)端的開發(fā)也成了一個(gè)重要的方向,但由于設(shè)備的不統(tǒng)一會(huì)造成一些兼容性問題, 1、安卓瀏覽器看背景圖...
    聶嘚吧嘚閱讀 1,990評(píng)論 3 13
  • 1 ie6.0橫向margin加倍 產(chǎn)生因素:塊屬性、float、有橫向margin。 解決方法:display:...
    han2019閱讀 763評(píng)論 0 1
  • 隨著手機(jī)的普及,移動(dòng)端的開發(fā)也成了一個(gè)重要的方向,但由于設(shè)備的不統(tǒng)一會(huì)造成一些兼容性問題, 1、安卓瀏覽器看背景圖...
    陽光嘚猴子閱讀 36,750評(píng)論 0 12
  • Ba la la la ~ 讀者朋友,你們好啊,又到了冷鋒時(shí)間,話不多說,發(fā)車! 1.<!DOCTYPE...
    王飽飽閱讀 469評(píng)論 0 1

友情鏈接更多精彩內(nèi)容