實際項目開放中,特別是電商項目,由於有大量的圖片加載必然會影響性能,所以實現圖片的懶加載是非常有必要的。
實現圖片懶加載的知識點
標簽的data-屬性 可視區域的監聽
實現圖片懶加載的原理
<img alt="loading..." data-src="images/1.jpg">
當我們監聽到圖片進入可視區域后,就將data-src到值賦值給src屬性
<script>
var images = document.querySelectorAll('img');
//ES6方法,也可以直接使用for語句
Array.from(images).forEach((el)=>{
el.src = el.dataset.src;
})
</script>
Element.getBoundingClientRect()方法
rectObject = object.getBoundingClientRect();
返回值是一個 DOMRect 對象,這個對象是由該元素的 getClientRects() 方法返回的一組矩形的集合, 即:是與該元素相關的CSS 邊框集合 。DOMRect 對象包含了一組用於描述邊框的只讀屬性——left、top、right和bottom,單位為像素。除了 width 和 height 外的屬性都是相對於視口的左上角位置而言的。

通過這個API,我們就很容易獲取img元素相對於視口的頂點位置"rectObject.top",只要這個值小於瀏覽器的高度(window.innerHeight)就說明進入可視區域。如果要提前加載,可以添加將瀏覽器的高度加值。
function isInSight(el){
const bound = el.getBoundingClientRect();
const clientHeight = window.innerHeight;
return bound.top <= clientHeight + 100;
}
實現圖片加載
function loadImg(el){
if(!el.src){
const source = el.dataset.src;
el.src = source;
}
}
將判斷進入可視區域的函數與加載圖片的函數放入頁面函數,在頁面加載與滾動的時候調用函數
function checkImgs(){
const imgs = document.querySelectorAll('li img');
Array.from(imgs).forEach(el =>{
if (isInSight(el)){
loadImg(el);
}
})
}
window.onload = function(){
checkImgs();
}
document.onscroll = function () {
checkImgs();
}
到這里就完成了圖片懶加載,但會存在一些性能問題,比如:加載過的圖片不需要在遍歷了、兩次滾動時間間隔很短(抖動問題)。這些優化問題就不在這兒寫了,以后有時間再補上去。接下來會寫另一個ES6實現圖片懶加載的API——“IntersectionObserver”,這個API實現性能會更好。
