面試判斷元素是否在可視區(qū)域中IntersectionObserver詳解
前言
我們面試中常見(jiàn)的一個(gè)問(wèn)題,如何判斷元素是否在可視區(qū)域中(即視口區(qū)域)?第一時(shí)間想到的肯定就是通過(guò),offsetHeight、clientHeight、scrollHeight、scrrollTop、window.innerHeight等等東西來(lái)計(jì)算。而IntersectionObserver更好的幫我們解決了這個(gè)問(wèn)題。
應(yīng)用場(chǎng)景
去實(shí)現(xiàn)懶加載、無(wú)限滾動(dòng)等等操作。
例:使用到的場(chǎng)景就是大量數(shù)據(jù)展示問(wèn)題,一次性渲染大量數(shù)據(jù),肯定會(huì)出現(xiàn)渲染性能問(wèn)題。如:一個(gè)select選擇框,有大量數(shù)據(jù),而視口展示的內(nèi)容只有其中一小小部分。我們只需要先渲染視口展示的內(nèi)容,當(dāng)用戶滾動(dòng)的時(shí)候,再渲染剩下的數(shù)據(jù)。這也是為什么在面試中要問(wèn)這個(gè)問(wèn)題。
使用
先放鏈接IntersectionObserver - Web API 接口參考 | MDN (mozilla.org)
IntersectionObserver
接口(從屬于 Intersection Observer API)提供了一種異步觀察目標(biāo)元素與其祖先元素或頂級(jí)文檔視口(viewport)交叉狀態(tài)的方法。其祖先元素或視口被稱為根(root)
當(dāng)一個(gè) IntersectionObserver
對(duì)象被創(chuàng)建時(shí),其被配置為監(jiān)聽(tīng)根中一段給定比例的可見(jiàn)區(qū)域。一旦 IntersectionObserver
被創(chuàng)建,則無(wú)法更改其配置,所以一個(gè)給定的觀察者對(duì)象只能用來(lái)監(jiān)聽(tīng)可見(jiàn)區(qū)域的特定變化值;然而,你可以在同一個(gè)觀察者對(duì)象中配置監(jiān)聽(tīng)多個(gè)目標(biāo)元素。
現(xiàn)在就用一個(gè)例子演示:
<ul> <li ref="li" v-for="(item, index) in lis" :key="index">{{ item }}</li> </ul> const lis = reactive([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
我這里創(chuàng)建了一個(gè)ul 里面有很多?。?0個(gè))li。然后我們想實(shí)現(xiàn)懶加載就需要用到IntersectionObserver這個(gè)API
第一步:先要獲取需要監(jiān)聽(tīng)元素的DOM,那我們這里需要獲取滾動(dòng)條數(shù)據(jù)的最后一個(gè)元素,也就是:li.value[li.value.length - 1]
(即li的最后一個(gè)DOM元素)。
const li = ref(null)
然后我們創(chuàng)建IntersectionObserver實(shí)例對(duì)象。 語(yǔ)法
var observer = new IntersectionObserver(callback[, options]);
這里有幾個(gè)參數(shù)解釋:
callback
當(dāng)元素可見(jiàn)比例超過(guò)指定閾值后,會(huì)調(diào)用一個(gè)回調(diào)函數(shù),此回調(diào)函數(shù)接受兩個(gè)參數(shù):
entries
一個(gè)IntersectionObserverEntry對(duì)象的數(shù)組,每個(gè)被觸發(fā)的閾值,都或多或少與指定閾值有偏差。
observer
被調(diào)用的IntersectionObserver實(shí)例。
const intersectionObserver = new IntersectionObserver((entries) => { // 如果 intersectionRatio 為 0,則目標(biāo)在可視區(qū)域之外, //直接return if (entries[0].intersectionRatio <= 0) return //停止在前一個(gè)DOM的監(jiān)聽(tīng)。 intersectionObserver.disconnect(li.value[li.value.length - 1]) //如過(guò)在可視區(qū)域之內(nèi),則我們添加數(shù)據(jù)。 lis.push(...[1, 2, 3, 4, 5, 6]) //更新監(jiān)聽(tīng)的DOM intersectionObserver.observe(li.value[li.value.length - 1]) console.log('Loaded new items') }) onMounted(() => { //這里對(duì)li的最后一個(gè)組件進(jìn)行監(jiān)聽(tīng)。 intersectionObserver.observe(li.value[li.value.length - 1]) })
這樣就能夠?qū)崿F(xiàn)一個(gè)懶加載的效果。
由此可見(jiàn)IntersectionObserver是多么的方便,而且還節(jié)省性能。
結(jié)語(yǔ)
IntersectionObserver現(xiàn)在對(duì)絕大多數(shù)瀏覽器都兼容,對(duì)于極個(gè)別可能不支持,在我們?nèi)粘i_(kāi)發(fā)中也可以提供很大幫助。
雖然現(xiàn)在的組件庫(kù)多種多樣,且許多地方都已經(jīng)自帶了懶加載的操作方法,無(wú)需了解其原理。但如果想要我們的技術(shù)更上一個(gè)臺(tái)階需要更加去了解。
參考資料 IntersectionObserver - Web API 接口參考 | MDN (mozilla.org)
以上就是面試判斷元素是否在可視區(qū)域中IntersectionObserver詳解的詳細(xì)內(nèi)容,更多關(guān)于IntersectionObserver可視區(qū)域的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
js實(shí)現(xiàn)簡(jiǎn)單頁(yè)面全屏
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)簡(jiǎn)單頁(yè)面全屏的功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09全面了解構(gòu)造函數(shù)繼承關(guān)鍵apply call
下面小編就為大家?guī)?lái)一篇全面了解構(gòu)造函數(shù)繼承關(guān)鍵apply call。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07分享9個(gè)最好用的JavaScript開(kāi)發(fā)工具和代碼編輯器
這篇文章主要介紹了9個(gè)最好用的JavaScript開(kāi)發(fā)工具和代碼編輯器,需要的朋友可以參考下2015-03-03Javascript圖像處理—平滑處理實(shí)現(xiàn)原理
這里直接引用OpenCV 2.4+ C++ 平滑處理和OpenCV 2.4+ C++ 邊緣梯度計(jì)算的相關(guān)內(nèi)容平滑也稱模糊, 是一項(xiàng)簡(jiǎn)單且使用頻率很高的圖像處理方法,需要了解的朋友可以參考下2012-12-12一些常用的JavaScript函數(shù)(json)附詳細(xì)說(shuō)明
一些常用的JavaScript函數(shù)(json)附詳細(xì)說(shuō)明,學(xué)習(xí)js的朋友可以參考下。2011-05-05