圖片指令碼懶載入簡易版外掛 LazyLoad

清夜發表於2017-12-11

工作中需求中經常會用到圖片懶載入的功能,這種功能實現起來並不難,但一次性寫下來程式碼量也不會小。

網上類似的外掛倒是一大堆,但是功能完善邏輯嚴謹的體積太大,裡面包含了大量根本用不到的功能和程式碼,憑空增加檔案體積;至於體積小的,又總懷疑邏輯寫得清不清楚,會不會有什麼bug之類的,所以比較糾結。

索性有時間就自己寫了一個,下次再用到這個功能的時候,就不會再嫌棄這個嫌棄那個了,並且程式碼是自己寫的,就算有什麼bug,自己也知道該怎麼改,也能夠很輕鬆地根據實際需求增刪程式碼,避免陷入邏輯嚴謹但程式碼臃腫或者程式碼精簡但邏輯不嚴謹的懷疑之中。


簡單介紹

程式碼使用 ES6語法,這個外掛其實是一個 classbabel打包後相容到 IE9完全沒問題的,甚至更低或許也可以,沒試過,原生js無任何依賴,相容移動端與 pc端。

核心程式碼其實就幾行而已:

if ((rect.top > 0 && this.H + distance >= rect.top) || (rect.top < 0 && (rect.top + rect.height >= -this.distance))) {
        if ((rect.left > 0 && this.W + distance >= rect.left) || (rect.left < 0 && (rect.left + rect.width >= -this.distance))) {
          this.loadItem(ele)
          this.elements.splice(i, 1, null)
        }
}
複製程式碼

上述程式碼就是判斷元素有沒有出現在瀏覽器視窗內,以決定是否讓元素載入對應的圖片,並且將在圖片懶載入的同時,將元素從尚未懶載入的DOM集合中去掉,優化效能

這裡寫圖片描述


用法

只需要對這個類LazyLoad進行初始化即可:

let lazyload = new LazyLoad()
lazyload.init({elements: domObjList})
複製程式碼

為了更方便的傳參,lazyLoad類的 init方法接受 1Object型別的引數,此引數最多有 6個自有屬性,一個必選,五個可選。

引數名 型別 描述 預設值 是否必選
elements NodeElement 懶載入的元素DOM物件,例如使用 document.querySelector('.img')獲取的結果就是此型別
之所以沒有相容直接傳遞一個類名或者 id讓外掛自己獲取DOM物件,而是讓使用者自己傳入,這是一種權衡之後的結果,因為我覺得這個外掛主要的功能就是懶載入,如果因為多加了一個可有可無的選擇器功能而讓外掛變得臃腫,反而不美
-
distance number 當元素距離瀏覽器可視區域邊緣多遠時進行圖片的載入動作,距離單位是px 0
tag string 元素標籤上用於懶載入的屬性名,值為需要懶載入的圖片地址 data-src
frequency number 外掛通過監聽頁面的scrollresizetouchmove事件來不斷獲取元素的是否進入視野內的資訊,此引數用於事件節流,此值越小,則佔用的瀏覽器資源越多 14
isBg boolean 外掛支援直接的 img標籤懶載入,同時也可支援其他元素的背景圖片懶載入,預設是支援 img標籤的圖片懶載入 false
defaultImg string 在元素懶載入正確的圖片之前顯示的替代圖片,預設沒有 -

如果你想懶載入的圖片是一個 div的背景圖,並且將圖片地址附在 imgurl這個自定義屬性上,還規定當元素距離視野邊緣 50px時就開始進行懶載入,節流頻率為 20ms, 懶載入的替代圖片是 https://dummyimage.com/200x200/ff0ff0&text=66,例如:

<div class="bgBox" imgurl="http://exmple.com/1.png"></div>
複製程式碼

則需要這樣初始化:

let lazyload = new LazyLoad()
lazyload.init({elements: document.querySelectorAll('.bgBox'), distance: 50, tag: 'imgurl', frequency: 20, isBg: true, defaultImg: 'https://dummyimage.com/200x200/ff0ff0&text=66'})
複製程式碼

另外,需要注意的是,如果你再初始化並呼叫 init方法之後,頁面又追加了需要懶載入的元素,則需要再次呼叫 init方法,並將你新追加進來的元素DOM物件傳入 elements屬性,來將懶載入應用於新追加進來的元素上。

也就是類似於這種:

lazyload.init({elements: newDOMObj})
複製程式碼

算上空行和註釋也就100行左右的程式碼量,整個外掛就是一個 ES6class類定義的,所以邏輯看起來是很清晰的,沒有什麼道道,看一遍就知道是怎麼回事,可以很輕鬆地進行修改。

此小外掛已經放到 Github 上,別忘了 star哦~

相關文章