概念
MDN是这样说明的: Intersection Observer API 提供了一种异步检测目标元素与祖先元素或viewport 相交情况变化的方法。
构造函数IntersectionObserver
语法
const observer = new IntersectionObserver(callback[, options]);
参数:
-
callback:当元素可见比例超过指定阈值后,会调用一个回调函数,此回调函数接受两个参数:
entries
--- 由IntersectionObserverEntry
对象组成的数组 但每个被触发的阈值,都或多或少与指定阈值有偏差。observer
--- 返回被调用的IntersectionObserver
实例。
-
options: 可选参数
-
root
--- 指定根元素。用于检查目标的可见性。默认为浏览器视口。 -
如果指定为 null,也为浏览器视口。
-
必须是目标元素的父级元素。
-
-
rootMargin
--- 根元素的扩缩边距。其传值形式与 CSS 中 margin 一样,用于控制根元素每一边的扩缩(单位为 px 或%),从而控制计算根元素和目标元素的交集的区域范围,默认值是"0px 0px 0px 0px"。 -
threshold
--- 规定了一个监听目标与边界盒交叉区域的比例值,可以是一个具体的数值或是一组 0.0 到 1.0 之间的数组。若指定值为 0.0,则意味着监听元素即使与根有 1 像素交叉,此元素也会被视为可见。若指定值为 1.0,则意味着整个元素都在可见范围内时才算可见。。-
当传入数值类型时,只会触发一次。
-
当传入数组类型时,可触发多次。
- 如:[0,0.25,0.5,0.75,1]表示目标元素在跟元素的可见程度每多 25% 就执行一次回调
-
返回值:
一个新的IntersectionObserver
对像。
- 该对象会按照设定的阈值来监听目标元素。
- 调用自身的
observe()
方法开始对目标元素进行监听。
IntersectionObserverEntry
IntersectionObserverEntry 对象的七个属性都是只读属性:
target
返回目标元素,表示目前该对象正监听的元素isIntersecting
返回一个布尔值,目标元素刚出现在根元素可视区时返回 true;目标元素从根元素可视区消失返回 false;以上两种情况都会触发 callback 函数boundingClientRect
返回目标元素的矩形区域的信息,返回结果与element.getBoundingClientRect()相同rootBounds
返回根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回 nullintersectionRect
返回目标元素与视口(或根元素)的交叉区域的信息intersectionRatio返回目标元素的可见比例,即intersectionRect
占boundingClientRect
的比例,完全可见时为 1,完全不可见时小于等于 0time
返回一个记录从IntersectionObserver
的时间原点到交叉被触发的时间的时间戳
实战 vue3 图片懒加载指令
// 懒加载
const lazyLoad = (el: HTMLImageElement, binding: DirectiveBinding) => {
el.src = 'xxxx' // 给图片添加一个默认图
const observer = new IntersectionObserver((entries, observe) => {
entries.forEach(item => {
const target = item.target as HTMLImageElement
if (item.isIntersecting) {
target.src = binding.value.path
// 取消观察
observe.unobserve(item.target)
}
})
})
observer.observe(el)
}
const vLazy: ObjectDirective = {
mounted: lazyLoad
}
<div>
<img v-for="img in images" v-lazy="{ path: img.path }" style="width: 300px; height: 400px" />
</div>