工做中需求中常常會用到圖片懶加載的功能,這種功能實現起來並不難,但一次性寫下來代碼量也不會小。git
網上相似的插件卻是一大堆,可是功能完善邏輯嚴謹的體積太大,裏面包含了大量根本用不到的功能和代碼,憑空增長文件體積;至於體積小的,又總懷疑邏輯寫得清不清楚,會不會有什麼bug之類的,因此比較糾結。github
索性有時間就本身寫了一個,下次再用到這個功能的時候,就不會再嫌棄這個嫌棄那個了,而且代碼是本身寫的,就算有什麼bug,本身也知道該怎麼改,也可以很輕鬆地根據實際需求增刪代碼,避免陷入邏輯嚴謹但代碼臃腫或者代碼精簡但邏輯不嚴謹的懷疑之中。瀏覽器
代碼使用 ES6
語法,這個插件實際上是一個 class
,babel
打包後兼容到 IE9
徹底沒問題的,甚至更低或許也能夠,沒試過,原生js
無任何依賴,兼容移動端與 pc
端。bash
核心代碼其實就幾行而已:babel
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
集合中去掉,優化性能dom
只須要對這個類LazyLoad
進行初始化便可:性能
let lazyload = new LazyLoad()
lazyload.init({elements: domObjList})
複製代碼
爲了更方便的傳參,lazyLoad
類的 init
方法接受 1
個 Object
類型的參數,此參數最多有 6
個自有屬性,一個必選,五個可選。優化
參數名 | 類型 | 描述 | 默認值 | 是否必選 |
---|---|---|---|---|
elements |
NodeElement |
懶加載的元素DOM 對象,例如使用 document.querySelector('.img')獲取的結果就是此類型 之因此沒有兼容直接傳遞一個類名或者 id 讓插件本身獲取DOM 對象,而是讓使用者本身傳入,這是一種權衡以後的結果,由於我以爲這個插件主要的功能就是懶加載,若是由於多加了一個無關緊要的選擇器功能而讓插件變得臃腫,反而不美 |
- | 是 |
distance |
number |
當元素距離瀏覽器可視區域邊緣多遠時進行圖片的加載動做,距離單位是px |
0 |
否 |
tag |
string |
元素標籤上用於懶加載的屬性名,值爲須要懶加載的圖片地址 | data-src |
否 |
frequency |
number |
插件經過監聽頁面的scroll 、resize 和touchmove 事件來不斷獲取元素的是否進入視野內的信息,此參數用於事件節流,此值越小,則佔用的瀏覽器資源越多 |
14 |
否 |
isBg |
boolean |
插件支持直接的 img 標籤懶加載,同時也可支持其餘元素的背景圖片懶加載,默認是支持 img 標籤的圖片懶加載 |
false |
否 |
defaultImg |
string |
在元素懶加載正確的圖片以前顯示的替代圖片,默認沒有 | - | 否 |
若是你想懶加載的圖片是一個 div
的背景圖,而且將圖片地址附在 imgurl
這個自定義屬性上,還規定當元素距離視野邊緣 50px
時就開始進行懶加載,節流頻率爲 20ms
, 懶加載的替代圖片是 https://dummyimage.com/200x200/ff0ff0&text=66
,例如:ui
<div class="bgBox" imgurl="http://exmple.com/1.png"></div>
複製代碼
則須要這樣初始化:this
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行左右的代碼量,整個插件就是一個 ES6
的 class
類定義的,因此邏輯看起來是很清晰的,沒有什麼道道,看一遍就知道是怎麼回事,能夠很輕鬆地進行修改。
此小插件已經放到 Github 上,別忘了 star
哦~