http://www.ovaldi.org/2015/09/11/%E4%BB%A5%E5%85%A8%E5%B1%80%E7%9B%91%E5%90%AC%E7%9A%84%E6%96%B9%E5%BC%8F%E5%A4%84%E7%90%86img%E7%9A%84error%E4%BA%8B%E4%BB%B6/
在開發一些電商頁面時,往往會有大量的商品圖片信息,當圖片加載失敗時,我們希望以一種更加友好的的方式改善用戶體驗:比如,換成一張友好的提示圖片。
img標簽在加載失敗時,會觸發error事件,所以,我們可以這么做
$(
"img").on("error", function(){
this.src = "/img/hint.jpg";
});
無法監聽到動態產生的img標簽然而,這種處理方法存在兩個問題:
- 給每一個img元素都綁定事件處理函數帶來的頁面性能損耗
那么,如何解決上面的問題呢?也許你會說利用事件冒泡的機制來監聽,可惜error事件並不會冒泡!
(事實上,在W3C的DOM Level 2 Events中規定,error事件是會冒泡的,而在DOM Level 3 Events中規定,error事件是不會冒泡的。)
要解決上述兩個問題,我們需要先了解一下DOM事件發生的三個階段:
- 捕獲階段: 從根節點開始順序而下,檢測每個節點是否注冊了事件處理函數。在標准瀏覽器中,我們可以通過指定addEventListener的第三個參數useCapture為true,以使事件處理函數在該階段運行。(低版本IE中無法指定事件處理函數在該階段執行)
- 目標階段: 觸發在目標對象本身注冊的事件處理函數,也稱正常事件派發階段。
- 冒泡階段: 從目標節點到根節點,檢測每個節點是否注冊了事件處理函數。在標准瀏覽器中,我們可以通過指定addEventListener的第三個參數useCapture為true,以使事件處理函數在該階段運行。
通過了解以上三個階段,我們就可以使用如下代碼解決:
document.addEventListener("error", function(e){
var elem = e.target;
if(elem.tagName.toLowerCase() === 'img'){
elem.src =
"/img/hint.jpg";
}
},
true /*指定事件處理函數在捕獲階段執行*/);
需要注意的是,由於低版本IE中attachEvent方法無法指定事件處理函數在捕獲階段執行,所以,該方案在低版本IE中不能適用。