前言:在以前的开发中,对于页面滚动到指定元素的监听,一般都是使用对document的onscroll进行,而现在有一个api可以简化这个操作,那就是IntersectionObserver接口。
概念
IntersectionObserver接口提供了一种异步观察目标元素与祖先元素或视窗元素交叉状态的方法。
使用
var IntersectionObserver: new (callback: IntersectionObserverCallback, options?: IntersectionObserverInit) => IntersectionObserver
上面为IntersectionObserver接口的类型定义,通过new关键字并且传入回调函数及配置对象,会返回一个观察者对象。
IntersectionObserver的方法
const intersectionObserver = new IntersectionObserver((entries) => {
console.log(entries[0])
})
const button = document.querySelector('button')
// 开始监听一个目标元素,可多次调用,以添加多个
intersectionObserver.observe(button)
// 取消对目标元素的监听
intersectionObserver.unobserve(button)
// 关闭观察器
intersectionObserver.disconnect()
// 返回当前观察器上的所有观察目标的IntersectionObserverEntry对象数组
intersectionObserver.takeRecords()
callback参数
当目标元素的可见性发生改变时,callback函数就会触发。
因此callback在元素出现和隐藏时都会触发,这就需要在函数内根据需求处理相关操作。
在callback函数内会传递一个entries参数,此参数为一个IntersectionObserverEntry对象数组,当同时有多个目标元素状态发生改变时,此参数的的长度就会有多个。
const intersectionObserver = new IntersectionObserver((entries) => {
console.log(entries)
})
const button = document.querySelectorAll('button')
// 添加多个目标元素,因此在进入页面后
// 触发回调函数里的entries的长度就会是2个
// 随着页面滚动entries的长度将由目标元素状态的变化决定。
intersectionObserver.observe(button[0])
intersectionObserver.observe(button[1])
option
interface IntersectionObserverInit {
// 祖先元素,不配置将使用视窗
root?: Element | Document | null;
// 定义根元素的margin,默认值为"0px 0px 0px 0px"
rootMargin?: string;
// 一个包含阈值的列表,按升序排列,默认0
// example: [0.25, 0.5, 1]
threshold?: number | number[];
}
root: 指定目标元素相对的容器,必须为目标元素的祖先节点。
rootMargin: 定义祖先元素的margin值,可以使用px和%百分比来定义。
threshold:决定了什么时候触发回调函数
IntersectionObserverEntry
interface IntersectionObserverEntry {
// 目标元素的矩形区域信息,既getBoundingClientRect()方法的返回值
readonly boundingClientRect: DOMRectReadOnly;
// 目标元素的可见比例,0-1
readonly intersectionRatio: number;
// 目标元素与根元素交叉的矩形区域信息
readonly intersectionRect: DOMRectReadOnly;
// 是否交叉
readonly isIntersecting: boolean;
// 根元素的矩形区域信息
readonly rootBounds: DOMRectReadOnly | null;
// 目标元素
readonly target: Element;
// 可见状态发生变化的时间,单位为毫秒
readonly time: DOMHighResTimeStamp;
}
以上即为IntersectionObserver相关的属性、方法、返回值,及其使用。
用途
滚动触底或触顶加载下一页
var intersectionObserver = new IntersectionObserver((entries) => {
if (entries[0].intersectionRatio <= 0) return;
// 加载下一页
loadPage(10);
});
intersectionObserver.observe(document.querySelector('.loading'));
css动画出现运动,隐藏停止
var intersectionObserver = new IntersectionObserver((entries) => {
const target = entries[0].target as HTMLDivElement
if (entries[0].intersectionRatio > 0) {
target.style.animationPlayState = 'running';
} else {
target.style.animationPlayState = 'paused';
}
});
intersectionObserver.observe(document.querySelector('.loading'));
根据需求用于其他用途...
注意点
此接口为异步方法,不随页面滚动同步触发。
既只有线程空闲下来的时候才会触发,优先级较低。
参考文章
https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver
http://ruanyifeng.com/blog/2016/11/intersectionobserver_api.html