視頻地址,或在bilibili,騰訊視頻搜索【冰山工做室】瀏覽器
看到這個問題,咱們應該先想一下一般是如何處理圖片加載失敗的
若是圖片加載失敗時會觸發 error 事件,那麼就容易了,只要爲每一個 img 標籤添加上內聯事件 onerror 就能夠了微信
<img src="aaa.jpg" onerror="this.src='placeholder.jpg'">
可是不是還能夠優化一下呢函數
<img src="aaa.jpg" onerror="errorHandler(this, event)"> <script> window.errorHandler = function(target, event){ target.src = 'placeholder.jpg'; } </script>
這彷佛已經知足題目的要求,可是真的沒有可優化的地方了麼?優化
以上兩點在一些嚴格執行編碼規範的團隊中是不能接受的this
那麼有什麼辦法呢?編碼
由於 error 事件沒法冒泡,可是事件傳播只有冒泡一種方式麼,還有捕獲
查規範可知,error 事件是能夠捕獲的,那麼就能夠實現以下代碼spa
function imgErrorHandler(){ window.addEventListener('error', function(e){ if( e.target.tagName === 'IMG' ){ e.target.src = 'placeholder.jpg'; } }, true); }
這樣就能夠不用擔憂有人在 img 標籤上漏寫 onerror 內聯事件了,由於根本不須要寫了,也不會再暴露全局函數,只須要在頁面渲染的過程當中執行一下上面的函數就能夠了
接下來能夠擴展一下功能:3d
必然存在不一樣的場景下圖片加載失敗顯示不一樣的佔位圖的需求,那麼咱們能夠在 img 標籤上添加一個 data-placeholder 屬性,標明一下當前場景想要顯示的佔位圖是什麼
當徹底斷網的時候,必然什麼圖片都沒法加載,必然致使錯誤處理被無限觸發,能夠標記一個計數器,當達到指望的數值時中止繼續請求,改成提供一個 Base64 的圖片路徑code
這樣代碼就擴展以下:視頻
const PLACE_HOLDER_IMG_LIST = { default: 'placeholder.jpg' , offline: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' , avatar: 'userAvatar.jpg' , photo: 'photo.jpg' } ; function imgErrorHandler(){ window.addEventListener('error', function(e){ let {target} = e , {placeholder = 'default', timer = 0} = target.dataset ; if( target.tagName === 'IMG' ){ timer = parseInt( timer ); if( timer < 3 ){ target.src = PLACE_HODLDER_IMG_LIST[placeholder]; target.dataset.timer = timer +1; } else{ target.src = PLACE_HOLDER_IMG_LIST.offline; } } }, true); }
擴展閱讀
根據規範:Once the propagation path has been determined, the event object passes through one or more event phases. 一旦肯定了傳播路徑,事件對象就會經過一個或多個事件階段。即每一個事件都會有捕獲階段,但不必定會有冒泡階段。好比 focus、blur 事件都是不冒泡的,可是倒是能夠被捕獲的.隨着 IE 瀏覽器逐漸退出歷史舞臺,傳統的以事件冒泡的開發方式也許會發生改變.尤爲在移動端,一些 touch 事件庫已經使用捕獲的方式來執行.捕獲階段必定會在冒泡階段以前,因此理論上能更快的響應
同時你也能夠關注咱們的微信公衆號:冰山工做室
有興趣的同窗能夠破解咱們的二維碼來加入社團:二維碼破解處?不服來戰