懶加載的好處就不扯了,如何實(shí)現(xiàn)呢?早期處理...
<!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>Document</title>
<style>
*{
margin: 0;padding: 0
}
</style>
</head>
<body>
<ul>
<li><img data-s="http://pic17.photophoto.cn/20101227/0009021186753392_b.jpg" alt="" src="https://p1.ssl.qhimgs1.com/sdr/400__/t01c2def919778941fb.jpg"></li>
<li><img data-s="http://pic15.photophoto.cn/20100613/0005018304692461_b.jpg" alt="" src="https://p1.ssl.qhimgs1.com/sdr/400__/t01c2def919778941fb.jpg"></li>
<li><img data-s="http://hbimg.b0.upaiyun.com/ac502031c2c7cf1e48b8a2e5964364c9603ea46210488-ruhT6l_fw658" alt="" src="https://p1.ssl.qhimgs1.com/sdr/400__/t01c2def919778941fb.jpg"></li>
<li><img data-s="http://img.52z.com/upload/news/image/20180213/20180213064608_79494.jpg" alt="" src="https://p1.ssl.qhimgs1.com/sdr/400__/t01c2def919778941fb.jpg"></li>
<li><img data-s="http://uploads.5068.com/allimg/1808/196-1PPZ94146.jpg" alt="" src="https://p1.ssl.qhimgs1.com/sdr/400__/t01c2def919778941fb.jpg"></li>
<li><img data-s="http://uploads.5068.com/allimg/1712/151-1G204092507.jpg" alt="" src="https://p1.ssl.qhimgs1.com/sdr/400__/t01c2def919778941fb.jpg"></li>
</ul>
</body>
<script>
let imgs = document.querySelectorAll('img')
let clientHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
function lazyLoadImg () {
for (let i = 0; i < imgs.length; i ++) {
if((imgs[i].getBoundingClientRect().top + imgs[i].height)>=0&&imgs[i].getBoundingClientRect().top < clientHeight){
imgs[i].src = imgs[i].getAttribute('data-s')
}
}
}
window.addEventListener('scroll', lazyLoadImg);
</script>
</html>
src是網(wǎng)絡(luò)數(shù)據(jù)可直接復(fù)制
這里為什么使用data- 命名屬性巧还,因為HTMLElement早之前支持了dataset屬性(早期介紹過)
原理很簡單穗泵,就是圖片的位置與滾動條高度的邏輯處理,那么這里使用了DOM的getBoundingClientRect()方法盗尸,獲取當(dāng)前DOM距離document四邊的距離
這是打印其中一個DOM元素的返回柑船,寬高,四邊距離都是直接計算出來的
imgs[i].getBoundingClientRect().top + imgs[i].height
就是當(dāng)前圖片距離document頭部的距離泼各,如果此時滾動條的高度>此高度就說明當(dāng)前viewport已經(jīng)顯示了圖片的位置鞍时,此時改變src即可,邏輯還是比較簡單扣蜻,復(fù)制代碼看效果的時候可能有點(diǎn)看不出來
(imgs[i].getBoundingClientRect().top + imgs[i].height)>=0&&imgs[i].getBoundingClientRect().top < clientHeight-500)
更改一下邏輯逆巍,讓他多500px的位置再顯示
繼續(xù)往下拉才會觸發(fā)!莽使!
今天主要介紹另一種方法锐极,Intersection Observer
各種概念什么就不搬了,自己了解一下芳肌!那么這玩意的作用就是判斷DOM是否出現(xiàn)在了可視區(qū)灵再!這就很騷了(我們就需要做什么滾動條高度這種花里胡哨的判斷了)
<!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>Document</title>
<style>
*{
margin: 0;padding: 0
}
</style>
</head>
<body>
<ul>
<li><img data-s="http://pic17.photophoto.cn/20101227/0009021186753392_b.jpg" alt="" src="https://p1.ssl.qhimgs1.com/sdr/400__/t01c2def919778941fb.jpg"></li>
<li><img data-s="http://pic15.photophoto.cn/20100613/0005018304692461_b.jpg" alt="" src="https://p1.ssl.qhimgs1.com/sdr/400__/t01c2def919778941fb.jpg"></li>
<li><img data-s="http://hbimg.b0.upaiyun.com/ac502031c2c7cf1e48b8a2e5964364c9603ea46210488-ruhT6l_fw658" alt="" src="https://p1.ssl.qhimgs1.com/sdr/400__/t01c2def919778941fb.jpg"></li>
<li><img data-s="http://img.52z.com/upload/news/image/20180213/20180213064608_79494.jpg" alt="" src="https://p1.ssl.qhimgs1.com/sdr/400__/t01c2def919778941fb.jpg"></li>
<li><img data-s="http://uploads.5068.com/allimg/1808/196-1PPZ94146.jpg" alt="" src="https://p1.ssl.qhimgs1.com/sdr/400__/t01c2def919778941fb.jpg"></li>
<li><img data-s="http://uploads.5068.com/allimg/1712/151-1G204092507.jpg" alt="" src="https://p1.ssl.qhimgs1.com/sdr/400__/t01c2def919778941fb.jpg"></li>
</ul>
</body>
<script>
let imgs = document.querySelectorAll('img')
var io = new IntersectionObserver((entries)=>{
entries.forEach((item) => { // 遍歷entries數(shù)組
if(item.isIntersecting){ // 當(dāng)前元素可見
item.target.src = item.target.dataset.s // 替換src
io.unobserve(item.target) // 停止觀察當(dāng)前元素 避免不可見時候再次調(diào)用callback函數(shù)
}
})
},{
})
imgs.forEach((item)=>{
io.observe(item)
})
</script>
</html>
簡單介紹一下用法:
new IntersectionObserver(callback,options)
IntersectionObserver是瀏覽器原生提供的構(gòu)造函數(shù)亿笤,接受兩個參數(shù):callback是可見性變化時的回調(diào)函數(shù)翎迁,option是配置對象(該參數(shù)可選)。
比如我們現(xiàn)在聲明一個對象
var io = new IntersectionObserver(callback, option);
// 開始觀察 DOM元素净薛,僅僅一個節(jié)點(diǎn)汪榔,多個需遍歷
io.observe(document.getElementById('example'));
// 停止觀察
io.unobserve(element);
// 關(guān)閉觀察器
io.disconnect();
目標(biāo)元素的可見性變化時,就會調(diào)用觀察器的回調(diào)函數(shù)callback
callback一般會觸發(fā)兩次肃拜。一次是目標(biāo)元素剛剛進(jìn)入視口(開始可見)痴腌,另一次是完全離開視口(開始不可見)雌团。
var io = new IntersectionObserver(
entries => {
console.log(entries);
}
);
我們來看看返回什么
let imgs = document.querySelectorAll('img')
var io = new IntersectionObserver(entries=>{
console.log(entries)
})
io.observe(imgs[0])
那么這里的isIntersecting 代表是否可見元素!因為我當(dāng)前監(jiān)聽的是第一張圖士聪,所以這里是true辱姨,如果換成第四張就是false了,當(dāng)前不在可視窗內(nèi)
intersectionRatio是指元素的可見比例戚嗅,就是有多少漏外面讓你看到了
target就是當(dāng)前元素信息雨涛,這里有個dataset屬性,所以命名里面的屬性加個data前綴
那么條件里面的代碼就可以看懂了
當(dāng)元素可見的時候 item.isIntersecting
item.target.src = item.target.dataset.s // 替換src
io.unobserve(item.target) 此時停止監(jiān)聽
框架就比較方便了懦胞,引入插件 v-lazy一下什么的L婢谩!谷歌也是支持了loading=lazy躏尉,但是不是所有圖片都像谷歌這么囂張的蚯根!