談談IntersectionObserver懶加載

概念

IntersectionObserver接口(從屬於Intersection Observer API)爲開發者提供了一種能夠異步監聽目標元素與其祖先或視窗(viewport)交叉狀態的手段。祖先元素與視窗(viewport)被稱爲根(root)。javascript

這是MDN上給的官方概念,不用去管它,我粘出來只是爲了顯得專業點嘛...css

重點看這裏監聽目標元素與其祖先或視窗交叉狀態的手段,其實就是觀察一個元素是否在視窗可見。java

是否可見

能夠看到,交叉了就是說明當前元素在視窗裏,當前就是可見的了。git

API

var io = new IntersectionObserver(callback, options)
複製代碼

其實就是一個簡單的構造函數。github

以上代碼會返回一個IntersectionObserver實例,callback是當元素的可見性變化時候的回調函數,options是一些配置項(可選)。chrome

咱們使用返回的這個實例來進行一些操做。數組

io.observe(document.querySelector('img'))  開始觀察,接受一個DOM節點對象
io.unobserve(element)   中止觀察 接受一個element元素
io.disconnect() 關閉觀察器
複製代碼

options

root瀏覽器

用於觀察的根元素,默認是瀏覽器的視口,也能夠指定具體元素,指定元素的時候用於觀察的元素必須是指定元素的子元素bash

threshold異步

用來指定交叉比例,決定何時觸發回調函數,是一個數組,默認是[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,當觀察元素img0%、50%、100%時候就會觸發回調函數

rootMargin

用來擴大或者縮小視窗的的大小,使用css的定義方法,10px 10px 30px 20px表示top、right、bottom 和 left的值

const options = {
	root: document.querySelector('.box'),
	threshold: [0, 0.5, 1],
	rootMargin: '30px 100px 20px'
}
複製代碼

爲了方便理解,我畫了張圖,以下

options

首先咱們來看下圖上的問題,藍線是什麼呢?他就是我們定義的root元素,咱們添加了rootMargin屬性,將視窗的增大了,虛線就是如今的視窗,因此元素如今也就在視窗裏面了。

因而可知,root元素只有在rootMargin爲空的時候纔是絕對的視窗。

說了簡單的options,接下來咱們看下callback

callback

上面咱們說到,當元素的可見性變化時,就會觸發callback函數。

callback函數會觸發兩次,元素進入視窗(開始可見時)和元素離開視窗(開始不可見時)都會觸發

var io = new IntersectionObserver((entries)=>{
	console.log(entries)
})

io.observe($0)
複製代碼

以上代碼,請在chrome控制檯進行調試,這裏我使用了$0選擇了上一次我審查元素的選擇的節點

運行結果以下

運行結果

咱們能夠看到callback函數有個entries參數,它是個IntersectionObserverEntry對象數組,接下來咱們重點說下IntersectionObserverEntry對象

IntersectionObserverEntry

IntersectionObserverEntry提供觀察元素的信息,有七個屬性。

boundingClientRect 目標元素的矩形信息

intersectionRatio 相交區域和目標元素的比例值 intersectionRect/boundingClientRect 不可見時小於等於0

intersectionRect 目標元素和視窗(根)相交的矩形信息 能夠稱爲相交區域

isIntersecting 目標元素當前是否可見 Boolean值 可見爲true

rootBounds 根元素的矩形信息,沒有指定根元素就是當前視窗的矩形信息

target 觀察的目標元素

time 返回一個記錄從IntersectionObserver的時間到交叉被觸發的時間的時間戳

上面幾個矩形信息的關係以下

關係

👇 劃重點

intersectionRatioisIntersecting是用來判斷元素是否可見的,押題咯...

懶加載

好了,經過上面一些概念咱們大概瞭解了IntersectionObserver是個什麼東西,接下來咱們用它來寫點代碼,寫什麼呢?沒錯就是懶加載。

經過IntersectionObserver來實現懶加載,就簡單的多了,咱們只須要設置回調,判斷當前元素是否可見,再進行渲染操做就好了,而不用去關心內部的計算。

主要代碼以下

const io = new IntersectionObserver(()=>{ // 實例化 默認基於當前視窗
	
})  

let ings = document.querySelectorAll('[data-src]') // 將圖片的真實url設置爲data-src src屬性爲佔位圖 元素可見時候替換src

function callback(entries){  
	entries.forEach((item) => { // 遍歷entries數組
		if(item.isIntersecting){ // 當前元素可見
			item.target.src = item.target.dataset.src  // 替換src
			io.unobserve(item.target)  // 中止觀察當前元素 避免不可見時候再次調用callback函數
		}	
	})
}

imgs.forEach((item)=>{  // io.observe接受一個DOM元素,添加多個監聽 使用forEach
	io.observe(item)
})
	
複製代碼

本想錄制個GIF圖,使用Recordlt始終上傳不了,誰有好用的GIF圖錄制軟件請推薦個,不勝感激。。

吶,給你花🌹

因篇幅有限,完整代碼請戳github 😜

⚠️注意

目前IntersectionObserver是一個實驗中的功能,請酌情使用。

兼容性
相關文章
相關標籤/搜索