感謝阮一峯老師撰寫的很是詳細的教程html
實現的大體預覽:api
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>圖片懶加載</title>
<style> img { display: block; width: 100%; margin-bottom: 20px;
}
</style>
</head>
<body>
<img data-src="img/asher-ward-453238-unsplash.jpg" src="img/asher-ward-453238-unsplash.jpg" alt="">
<img data-src="img/asher-ward-453238-unsplash.jpg" src="img/asher-ward-453238-unsplash.jpg" alt="">
<img data-src="img/jay-mantri-4033-unsplash.jpg" alt="">
<img data-src="img/jp-valery-734900-unsplash.jpg" alt="">
<img data-src="img/ryan-searle-345035-unsplash.jpg" alt="">
<img data-src="img/thomas-tixtaaz-119883-unsplash.jpg" alt="">
</body>
<script> var imgs = document.querySelectorAll('img'); //offsetTop是元素與上一級父元素的距離,須要循環獲取直到獲得元素相對於頁面頂部的距離(即便在但是區域外) function getTop(e) { var T = e.offsetTop; while(e = e.offsetParent) { T += e.offsetTop;//當e=undefined,即獲取到最頂層,退出循環 } return T; } function lazyLoad(imgs) { var H = document.documentElement.clientHeight;//獲取可視區域高度 var S = document.documentElement.scrollTop || document.body.scrollTop;//是文檔的scrollTop屬性! for (var i = 0; i < imgs.length; i++) { if (H + S > getTop(imgs[i])) {//見示意圖 imgs[i].src = imgs[i].getAttribute('data-src'); } } } window.onload = window.onscroll = function () { //onscroll()在滾動條滾動的時候觸發 lazyLoad(imgs); } </script>
</html>
這個方法很容易理解,而且兼容性也不錯,可是有一個致命的缺點就是onscroll事件觸發的太頻繁了,很容易影響頁面性能。瀏覽器
於是考慮使用IntersectionObserver,這個api兼容性不好,須要谷歌51+。異步
//使用交叉觀察器進行實現 IntersectionObserver API
var observer = new IntersectionObserver(
function visible(eles){
eles.forEach(function(ele){
ele.target.src = ele.target.getAttribute('data-src');//注意這裏的ele是觀察器對象,ele.target纔是被觀察的元素
console.log(ele.target);
// observer.unobserve(this);//取消觀察
})
},{
threshold:[0,0.1],//可見比例達到...時觸發觀察器的回調函數
// root:document.documentElement//當元素在容器內滾動時的設定
});
//observe的參數是一個 DOM 節點對象。若是要觀察多個節點,就要屢次調用這個方法。
//也就是說,不能使用document.querySelector('img')
//這裏參考了阮一峯老師的教程
function query(selector){
return Array.from(document.querySelectorAll(selector));
};
query('img').forEach(function(item){
observer.observe(item);
})
//IntersectionObserver API 是異步的,不隨着目標元素的滾動同步觸發。
// 規格寫明,IntersectionObserver的實現,應該採用requestIdleCallback(),
// 即只有線程空閒下來,纔會執行觀察器。這意味着,這個觀察器的優先級很是低,只在其餘任務執行完,瀏覽器有了空閒纔會執行。