IntersectionObserver用来监听一个目标元素是否出现在web页面的可视区域。
传统方式监听一个元素是否出现在可视区,可以监听scroll事件,计算目标元素距离顶部的距离减去页面滑出的距离;如果大于0且小于窗口的高度则表明是可见的。
0 < $("targetDom").offset().top - $(document).scrollTop() < $(window).height()
但是此方法需监听scroll事件,对性能要求高。
IntersectionObserver API,可以自动"观察"元素是否可见,IntersectionObserver是浏览器原生提供的一个构造函数,第一个参数元素可见性发生变化的回调函数,第二个是配置参数(可选)
1. 创建一个观察实例
var io = new IntersectionObserver(callback, option);
// 开始观察
io.observe(document.getElementById('example'));
// 停止观察
io.unobserve(element);
// 关闭观察器
io.disconnect();
callback
callback会在元素刚开始进入视线和完全离开视线触发:
var io = new IntersectionObserver(
entries => {
console.log(entries);
}
)
回调函数返回IntersectionObserverEntry的对象有以下属性:
{
time: 3893.92,
rootBounds: ClientRect {
bottom: 920,
height: 1024,
left: 0,
right: 1024,
top: 0,
width: 920
},
boundingClientRect: ClientRect {
// ...
},
intersectionRect: ClientRect {
// ...
},
intersectionRatio: 0.54,
target: element
}
time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒
target:被观察的目标元素,是一个 DOM 节点对象
rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
boundingClientRect:目标元素的矩形区域的信息
intersectionRect:目标元素与视口(或根元素)的交叉区域的信息
intersectionRatio:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0
使用
new IntersectionObserver(function(entries) {
if (!(entries[0].intersectionRatio <= 0)) {
loadData()
}
}).observe(document.querySelector("targetDOM")),
Option 参数
1 threshold 属性
threshold属性决定了什么时候触发回调函数。对应的值是一个数组,默认是[0]
new IntersectionObserver(
entries => {/* ... */},
{
threshold: [0, 0.25, 0.5, 0.75, 1] //当目标元素 0%、25%、50%、75%、100% 可见时,会触发回调函数。
}
);
2 root 属性,rootMargin 属性
很多时候,目标元素不仅会随着窗口滚动,还会在容器里面滚动(比如在iframe窗口里滚动)。
var opts = {
root: document.querySelector('.container'),
rootMargin: "500px 0px"
};
var observer = new IntersectionObserver(
callback,
opts
);
上面代码中,除了root属性,还有rootMargin属性。后者定义根元素的margin,用来扩展或缩小rootBounds这个矩形的大小,从而影响intersectionRect交叉区域的大小。它使用CSS的定义方法,比如10px 20px 30px 40px,表示 top、right、bottom 和 left 四个方向的值。
这样设置以后,不管是窗口滚动或者容器内滚动,只要目标元素可见性变化,都会触发观察器。
IntersectionObserver API 是异步触发
只有线程空闲下来,才会执行观察器。这意味着,这个观察器的优先级非常低,只在其他任务执行完,浏览器有了空闲才会执行。
网友评论