用原生JS實現圖片懶載入
阿新 • • 發佈:2020-12-17
技術標籤:JSjavascript
之前專案都是使用現成的lazyLoad之類的懶載入外掛,趁專案沒那麼趕的時候自己試著實現一下。
思路
<img>
標籤屬性src的值不為空的時,瀏覽器就會根據這個值傳送請求。
所以我們可以先給所有的圖片設定一個loading的圖片,當圖片出現在瀏覽器的可視區域內時,才設定圖片真正的路徑,讓圖片顯示出來。
實現
HTML
<div class="container">
<div class="img-area">
<img class="my-photo" src="img/loading.png" alt="1" data-src="img/img1.png">
</div>
<div class="img-area">
<img class="my-photo" src="img/loading.png" alt="2" data-src="img/img2.png">
</div>
<div class ="img-area">
<img class="my-photo" src="img/loading.png" alt="3" data-src="img/img3.png">
</div>
<div class="img-area">
<img class="my-photo" src="img/loading.png" alt="4" data-src="img/img4.png">
</div>
<div class="img-area">
<img class="my-photo" src="img/loading.png" alt="5" data-src="img/img5.png">
</div>
<div class="img-area">
<img class="my-photo" src="img/loading.png" alt="6" data-src="img/img6.png">
</div>
<div class="img-area">
<img class="my-photo" src="img/loading.png" alt="7" data-src="img/img7.png">
</div>
</div>
注意:alt是必須的屬性,它規定在影象無法顯示時的替代文字。
data-* 全域性屬性:構成一類名稱為自定義資料屬性的屬性,可以通過HTMLElement.dataset來訪問。
判斷元素在可視區內
function isInArea(el) {
const bound = el.getBoundingClientRect();
const clientHeight = window.innerHeight;
return bound.top <= clientHeight;
}
載入圖片
頁面開啟時需要對所有圖片進行判斷,在可視區內就載入。
function checkImgs() {
const imgs = document.querySelectorAll('.my-photo');
Array.from(imgs).forEach(el => {
if (isInArea(el)) {
loadImg(el);
}
})
}
function loadImg(el) {
if (el.src==="img/loading.png") {
const source = el.dataset.src;
el.src = source;
}
}
這裡可以做一個優化的地方,設一個識別符號標識已經載入圖片的index,當滾動條滾動時就不需要遍歷所有的圖片,只需要遍歷未載入的圖片即可。
函式節流
因為onScroll這種頻繁的DOM操作,也會影響頁面效能,所以我們可以做個節流優化。
function throttle(fn, mustRun = 300) {
const timer = null;
let previous = null;
return function() {
const now = new Date();
const context = this;
const args = arguments;
if (!previous){
previous = 0;
}
const remaining = now - previous;
if (mustRun && remaining >= mustRun) {
fn.apply(context, args);
previous = now;
}
}
}
完成
這樣我們就實現了簡單的圖片懶載入~