前言
- 需求背景:需要监听某个元素的滚动位置触发对应事件(懒加载、无限滚动等),比如:
- 向下滚动时,显示/隐藏某个元素;
- 元素滚动进入某个区域/位置等
- 采取方案
- 传统方式:添加
scroll事件监听,时刻获取目标元素的滚动情况- 缺点:滚动事件会频繁触发,计算工作大,加重性能方面的负担
IntersectionObserverAPI:通过异步监听观察元素是否进入可见区域**,不需要时刻触发
- 传统方式:添加
IntersectionObserver API
-
定义:一种异步观察目标元素与规定的视窗的交叉状态的方法(不随目标元素滚动同步触发)
- 目标元素:需要监听的DOM节点元素
- 视窗:默认是网页可见区域,也可自行设置,但必须是目标元素的祖先元素
-
创建对象实例:
var io = new IntersectionObserver(callback, options) -
配置触发参数:
options:(可选),属性如下:root/rootMargin:目标元素的祖先节点及其margin值threshold:数组阈值,达到或超过设定的值时触发回调 (可决定何时触发回调)
-
触发回调
callback(entries): 当目标元素与视口交叉(进入视口区域)时- 注意点:一般会触发两次,第一次是元素刚进入可视区,第二次是完全离开可视区
entries:数组,每一项表示一个观察元素与视窗的交叉状态对象(IntersectionObserverEntry)
-
IntersectionObserverEntry常用属性:time:可见性发生变化的时间target:被观察的目标 DOM 节点对象rootBounds:根元素的矩形区域的信息getBoundingClientRect()方法的返回值,没有根元素则返回null
boundingClientRect:目标元素的矩形区域intersectionRect:交叉区域的信息isIntersecting:true(有交叉区域);false(无交叉区域)intersectionRatio:目标元素在交叉区域可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0
-
方法:
- 开始观察目标节点:
io.observe(target)- target:观察目标DOM节点,监听多个节点需要多次调用
- 停止观察:
io.unobserve(target) - 关闭观察:
io.disconnect(target)
- 开始观察目标节点:
-
示例:页面视频滚动至不可见时暂停播放
- 观察目标元素:底部logo或者距离底部最近的可见元素
var io = new IntersectionObserver(handleObserve,{
threshold:[0]
})
var targetDom = document.getElementById('video')
//观察
io.observe(targetDom)
//监听回调
function handleObserve(entries){
if(entries[0].intersectionRatio === 0){
//视频不可见时,暂停视频
}
}
//不需要时停止观察
beforeDestroy(){
io.unobserve(targetDom)
io.disconnect()
}