【視頻教程】-圖片加載失敗模塊設計-冰山工做室-沙翼-web前端

視頻地址,或在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>

這彷佛已經知足題目的要求,可是真的沒有可優化的地方了麼?優化

  • 首先,這個作法的先決條件是要求每一個 img 標籤上都要求寫上 onerror 內聯事件,其它開發人員忘了寫怎麼辦?
  • 其次,在全局暴露了一個全局函數

以上兩點在一些嚴格執行編碼規範的團隊中是不能接受的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 事件庫已經使用捕獲的方式來執行.捕獲階段必定會在冒泡階段以前,因此理論上能更快的響應

同時你也能夠關注咱們的微信公衆號:冰山工做室

有興趣的同窗能夠破解咱們的二維碼來加入社團:二維碼破解處?不服來戰

clipboard.png

相關文章
相關標籤/搜索