談?wù)処ntersectionObserver懶加載的具體使用
概念
IntersectionObserver接口(從屬于Intersection Observer API)為開(kāi)發(fā)者提供了一種可以異步監(jiān)聽(tīng)目標(biāo)元素與其祖先或視窗(viewport)交叉狀態(tài)的手段。祖先元素與視窗(viewport)被稱為根(root)。
這是MDN上給的官方概念,不用去管它,我粘出來(lái)只是為了顯得專業(yè)點(diǎn)嘛...
重點(diǎn)看這里 監(jiān)聽(tīng)目標(biāo)元素與其祖先或視窗交叉狀態(tài)的手段 ,其實(shí)就是觀察一個(gè)元素是否在視窗可見(jiàn)。
可以看到,交叉了就是說(shuō)明當(dāng)前元素在視窗里,當(dāng)前就是可見(jiàn)的了。
API
var io = new IntersectionObserver(callback, options)
其實(shí)就是一個(gè)簡(jiǎn)單的構(gòu)造函數(shù)。
以上代碼會(huì)返回一個(gè) IntersectionObserver
實(shí)例, callback
是當(dāng)元素的可見(jiàn)性變化時(shí)候的回調(diào)函數(shù), options
是一些配置項(xiàng)(可選)。
我們使用返回的這個(gè)實(shí)例來(lái)進(jìn)行一些操作。
io.observe(document.querySelector('img')) 開(kāi)始觀察,接受一個(gè)DOM節(jié)點(diǎn)對(duì)象 io.unobserve(element) 停止觀察 接受一個(gè)element元素 io.disconnect() 關(guān)閉觀察器
options
root
用于觀察的根元素,默認(rèn)是瀏覽器的視口,也可以指定具體元素,指定元素的時(shí)候用于觀察的元素必須是指定元素的子元素
threshold
用來(lái)指定交叉比例,決定什么時(shí)候觸發(fā)回調(diào)函數(shù),是一個(gè)數(shù)組,默認(rèn)是 [0]
。
const options = { root: null, threshold: [0, 0.5, 1] } var io = new IntersectionObserver(callback, options) io.observe(document.querySelector('img'))
上面代碼,我們指定了交叉比例為0,0.5,1,當(dāng)觀察元素img0%、50%、100%時(shí)候就會(huì)觸發(fā)回調(diào)函數(shù)
rootMargin
用來(lái)擴(kuò)大或者縮小視窗的的大小,使用css的定義方法, 10px 10px 30px 20px
表示top、right、bottom 和 left的值
const options = { root: document.querySelector('.box'), threshold: [0, 0.5, 1], rootMargin: '30px 100px 20px' }
為了方便理解,我畫(huà)了張圖,如下
首先我們來(lái)看下圖上的問(wèn)題,藍(lán)線是什么呢?他就是咱們定義的root元素,我們添加了 rootMargin
屬性,將視窗的增大了,虛線就是現(xiàn)在的視窗,所以元素現(xiàn)在也就在視窗里面了。
由此可見(jiàn),root元素只有在 rootMargin
為空的時(shí)候才是絕對(duì)的視窗。
說(shuō)了簡(jiǎn)單的options,接下來(lái)我們看下 callback
。
callback
上面我們說(shuō)到,當(dāng)元素的可見(jiàn)性變化時(shí),就會(huì)觸發(fā)callback函數(shù)。
callback函數(shù)會(huì)觸發(fā)兩次,元素進(jìn)入視窗(開(kāi)始可見(jiàn)時(shí))和元素離開(kāi)視窗(開(kāi)始不可見(jiàn)時(shí))都會(huì)觸發(fā)
var io = new IntersectionObserver((entries)=>{ console.log(entries) }) io.observe($0)
以上代碼,請(qǐng)?jiān)赾hrome控制臺(tái)進(jìn)行調(diào)試,這里我使用了 $0
選擇了上一次我審查元素的選擇的節(jié)點(diǎn)
運(yùn)行結(jié)果如下
我們可以看到callback函數(shù)有個(gè) entries
參數(shù),它是個(gè) IntersectionObserverEntry
對(duì)象數(shù)組,接下來(lái)我們重點(diǎn)說(shuō)下IntersectionObserverEntry對(duì)象
IntersectionObserverEntry
IntersectionObserverEntry
提供觀察元素的信息,有七個(gè)屬性。
boundingClientRect 目標(biāo)元素的矩形信息 intersectionRatio 相交區(qū)域和目標(biāo)元素的比例值 intersectionRect/boundingClientRect 不可見(jiàn)時(shí)小于等于0 intersectionRect 目標(biāo)元素和視窗(根)相交的矩形信息 可以稱為相交區(qū)域 isIntersecting 目標(biāo)元素當(dāng)前是否可見(jiàn) Boolean值 可見(jiàn)為true rootBounds 根元素的矩形信息,沒(méi)有指定根元素就是當(dāng)前視窗的矩形信息 target 觀察的目標(biāo)元素 time 返回一個(gè)記錄從 IntersectionObserver
的時(shí)間到交叉被觸發(fā)的時(shí)間的時(shí)間戳
上面幾個(gè)矩形信息的關(guān)系如下
劃重點(diǎn)
intersectionRatio和 isIntersecting 是用來(lái)判斷元素是否可見(jiàn)的,押題咯...
懶加載
好了,通過(guò)上面一些概念我們大概了解了 IntersectionObserver
是個(gè)什么東西,接下來(lái)我們用它來(lái)寫(xiě)點(diǎn)代碼,寫(xiě)什么呢?沒(méi)錯(cuò)就是懶加載。
通過(guò)IntersectionObserver來(lái)實(shí)現(xiàn)懶加載,就簡(jiǎn)單的多了,我們只需要設(shè)置回調(diào),判斷當(dāng)前元素是否可見(jiàn),再進(jìn)行渲染操作就行了,而不用去關(guān)心內(nèi)部的計(jì)算。
主要代碼如下
const io = new IntersectionObserver(()=>{ // 實(shí)例化 默認(rèn)基于當(dāng)前視窗 }) let ings = document.querySelectorAll('[data-src]') // 將圖片的真實(shí)url設(shè)置為data-src src屬性為占位圖 元素可見(jiàn)時(shí)候替換src function callback(entries){ entries.forEach((item) => { // 遍歷entries數(shù)組 if(item.isIntersecting){ // 當(dāng)前元素可見(jiàn) item.target.src = item.target.dataset.src // 替換src io.unobserve(item.target) // 停止觀察當(dāng)前元素 避免不可見(jiàn)時(shí)候再次調(diào)用callback函數(shù) } }) } imgs.forEach((item)=>{ // io.observe接受一個(gè)DOM元素,添加多個(gè)監(jiān)聽(tīng) 使用forEach io.observe(item) })
本想錄制個(gè)GIF圖,使用Recordlt始終上傳不了,誰(shuí)有好用的GIF圖錄制軟件請(qǐng)推薦個(gè),不勝感激。。
吶,給你花:rose:
因篇幅有限,完整代碼請(qǐng)戳 github
注意
目前IntersectionObserver是一個(gè)實(shí)驗(yàn)中的功能,請(qǐng)酌情使用。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
兼容低版本IE的JScript5.5實(shí)現(xiàn)
兼容低版本IE的JScript5.5實(shí)現(xiàn)...2006-09-09JS中如何比較兩個(gè)Json對(duì)象是否相等實(shí)例代碼
這篇文章主要介紹了JS中如何比較兩個(gè)Json對(duì)象是否相等實(shí)例代碼的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-07-07javascript表單驗(yàn)證 - Parsley.js使用和配置
大家還記得我們?cè)?jīng)介紹過(guò)的表單驗(yàn)證jquery插件jquery.validationEngine吧;天介紹的Parsley同樣也可以幫助你只使用簡(jiǎn)單的配置即可實(shí)現(xiàn)表單驗(yàn)證功能,基于它的強(qiáng)大DOM-API,感興趣的你可以不要錯(cuò)過(guò)了哦2013-01-01基于JavaScript編寫(xiě)8086匯編指令查詢工具
匯編語(yǔ)言還是在大學(xué)的時(shí)候?qū)W的,匯編語(yǔ)言有個(gè)特點(diǎn)是語(yǔ)句短、條數(shù)多,很難可以把全部指令都背熟。本文就來(lái)用JavaScript編寫(xiě)一個(gè)8086匯編指令查詢工具,希望對(duì)大家有所幫助2023-02-02JavaScript數(shù)據(jù)結(jié)構(gòu)Number
這篇文章主要介紹了JavaScript數(shù)據(jù)結(jié)構(gòu)Number,Number?是JavaScript的基本數(shù)據(jù)結(jié)構(gòu),是對(duì)應(yīng)數(shù)值的應(yīng)用類(lèi)型,下文給大家分享JavaScript使用?Number?的常見(jiàn)問(wèn)題,需要的朋友可以參考一下2022-02-02只需一行代碼,輕松實(shí)現(xiàn)一個(gè)在線編輯器
在瀏覽器地址欄中輸入一行代碼:data:text/html, <html contenteditable> ,回車(chē)即可把瀏覽器變臨時(shí)編輯器(需要瀏覽器支持 HTML5 屬性 contenteditable)2013-11-11JavaScript實(shí)現(xiàn)拖拽元素對(duì)齊到網(wǎng)格(每次移動(dòng)固定距離)
最近在做一個(gè)拖拽元素的附加功能,就是對(duì)齊到網(wǎng)格,實(shí)際上就是確定好元素的初始位置,然后拖拽元素時(shí),每次移動(dòng)固定的距離。讓元素都可以在網(wǎng)格內(nèi)對(duì)齊2016-11-11