这是个还在草案中的API,不过大部分浏览器均已实现(除了IE)。先看下MDN中的介绍:javascript
IntersectionObserver接口提供了一种异步观察目标元素与祖先元素或顶级文档viewport的交集中的变化的方法。祖先元素与视窗viewport被称为根(root)。html
不知你们有没有发现随着网页发展,对检测某个(些)元素是否出如今可视窗相关的需求愈来愈多了?好比:java
一直以来,检测元素的可视状态或者两个元素的相对可视状态都不是件容易事,大部分解决办法并不彻底可靠,实现方式很丑陋,也极易拖慢整个网站的性能。web
IntersectionObserver正所以而生数组
是以new
的形式声明一个对象,接收两个参数callback
和options
浏览器
const io = new IntersectionObserver(callback, options)
io.observe(DOM)
复制代码
const options = {
root: null,
rootMargin: 0,
thresholds: 1,
}
const io = new IntersectionObserver(entries => {
console.log(entries)
// Do something
}, options)
复制代码
callback是添加监听后,当监听目标发生滚动变化时触发的回调函数。接收一个参数entries,即IntersectionObserverEntry实例。描述了目标元素与root的交叉状态。具体参数以下:异步
属性 | 说明 |
---|---|
boundingClientRect | 返回包含目标元素的边界信息,返回结果与element.getBoundingClientRect() 相同 |
intersectionRatio | 返回目标元素出如今可视区的比例 |
intersectionRect | 用来描述root和目标元素的相交区域 |
isIntersecting | 返回一个布尔值,下列两种操做均会触发callback:1. 若是目标元素出如今root可视区,返回true。2. 若是从root可视区消失,返回false |
rootBounds | 用来描述交叉区域观察者(intersection observer)中的根. |
target | 目标元素:与根出现相交区域改变的元素 (Element) |
time | 返回一个记录从 IntersectionObserver 的时间原点到交叉被触发的时间的时间戳 |
表格中加粗的两个属性是比较经常使用的判断条件:isIntersecting和intersectionRatioide
options是一个对象,用来配置参数,也能够不填。共有三个属性,具体以下:函数
属性 | 说明 |
---|---|
root | 所监听对象的具体祖先元素。若是未传入值或值为null ,则默认使用顶级文档的视窗(通常为html)。 |
rootMargin | 计算交叉时添加到根(root)边界盒bounding box的矩形偏移量, 能够有效的缩小或扩大根的断定范围从而知足计算须要。全部的偏移量都可用像素(px )或百分比(% )来表达, 默认值为"0px 0px 0px 0px"。 |
threshold | 一个包含阈值的列表, 按升序排列, 列表中的每一个阈值都是监听对象的交叉区域与边界区域的比率。当监听对象的任何阈值被越过期,都会触发callback。默认值为0。 |
介绍了这么多配置项及参数,差点忘了最重要的,IntersectionObserver有哪些方法? 若是要监听某些元素,则必需要对该元素执行一下observe性能
方法 | 说明 |
---|---|
observe() | 开始监听一个目标元素 |
unobserve() | 中止监听特定目标元素 |
takeRecords() | 返回全部观察目标的IntersectionObserverEntry对象数组 |
disconnect() | 使IntersectionObserver对象中止所有监听工做 |
const imgList = [...document.querySelectorAll('img')]
var io = new IntersectionObserver((entries) =>{
entries.forEach(item => {
// isIntersecting是一个Boolean值,判断目标元素当前是否可见
if (item.isIntersecting) {
item.target.src = item.target.dataset.src
// 图片加载后即中止监听该元素
io.unobserve(item.target)
}
})
}, {
root: document.querySelector('.root')
})
// observe遍历监听全部img节点
imgList.forEach(img => io.observe(img))
复制代码
假若有个需求,对一个页面中的特定元素,只有在其彻底显示在可视区内时进行埋点曝光。
const boxList = [...document.querySelectorAll('.box')]
var io = new IntersectionObserver((entries) =>{
entries.forEach(item => {
// intersectionRatio === 1说明该元素彻底暴露出来,符合业务需求
if (item.intersectionRatio === 1) {
// 。。。 埋点曝光代码
io.unobserve(item.target)
}
})
}, {
root: null,
threshold: 1, // 阀值设为1,当只有比例达到1时才触发回调函数
})
// observe遍历监听全部box节点
boxList.forEach(box => io.observe(box))
复制代码
用上面的例子随便写了一个,太丑勿喷
总之,这是一个至关方便好用的API!
参考连接🔗