IntersectionObserver--交叉观察器
初识Intersectionobserver
Intersectionobserver 接口(从属于 Intersection 0bserver API)提供了一种异步观察目标元素与其祖先元素或顶级文档视口(viewport)交叉状态的方法。其祖先元素或视口被称为根(rot)。当一个 Intersectionobserver 对象被创建时,其被配置为监听根中一段给定比例的可见区域。一旦 Intersectionoberver 被创建,则无法更改其配置,所以一个给定的观察者对象只能用来监听可见区域的特定变化值;然而,你可以在同一个观察者对象中配詈监听多个目标元素。
构造函数
创建一个新的’Intersectionobserver’对象,当其监听到目标元素的可见部分(的比例)超过了一个或多个闹值(threshold)时,会执行指定的回调函数
let observer =new Intersectionobserver()
// 由此就创建了-个Intersectionobserver 实例对象
实例属性
IntersectionObserver.root 只读
测试交叉时,用作边界盒的元素或文档。如果构造函数未传入 root 或其值为null,则默认使用顶级文档的视口。
IntersectionObserver.rootMargin 只读
计算交叉时添加到根边界盒的矩形偏移量,可以有效的缩小或扩大根的判定范围从而满足计算需要。此属性返回的值可能与调用构造函数时指定的值不同,因此可能需要更改该值,以匹配内部要求。所有的偏移量均可用像素(px)或百分比(%)来表达,默认值为“0px 0px 0px 0px”。
IntersectionObserver.thresholds 只读
一个包含阈值的列表,按升序排列,列表中的每个阈值都是监听对象的交叉区域与边界区域的比率。当监听对象的任何阈值被越过时,都会生成一个通知(Notification)。如果构造器未传入值,则默认值为 0。
实例方法
IntersectionObserver.disconnect()
使 IntersectionObserver 对象停止监听目标。
IntersectionObserver.observe()
使 IntersectionObserver 开始监听一个目标元素。
IntersectionObserver.takeRecords()
返回所有观察目标的 IntersectionObserverEntry 对象数组。
IntersectionObserver.unobserve()
使 IntersectionObserver 停止监听特定目标元素。
// 开始观察
observer.observe(document.getElementById('example'));
// 停止观察
observer.unobserve(element);
// 关闭观察器
observer.disconnect();
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()方法的返回值,如果没有容器元素(即直接相对于视口滚动),则返回nullboundingClientRect
:目标元素的矩形区域的信息intersectionRect
:目标元素与视口(或容器元素)的交叉区域的信息intersectionRatio
:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0
示例
简单用法
const intersectionObserver = new IntersectionObserver((entries) => {
// 如果 intersectionRatio 为 0,则目标在视野外,
// 我们不需要做任何事情。
if (entries[0].intersectionRatio <= 0) return;
loadItems(10);
console.log("Loaded new items");
});
// 开始监听
intersectionObserver.observe(document.querySelector(".scrollerFooter"));
场景应用·图片懒加载
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IntersectionObserver交叉监视器</title>
<style> *{
padding: 0px;
margin: 0px;
}
.scroll-one {
width: 100%;
height: 100vh;
background-color: #ececec;
}
.scroll-two {
width: 200px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
background-color: beige;
margin: 0 auto;
}
.scroll-two img {
width: 50%;
margin: 100px 0px;
}
.scroll-tree {
width: 100px;
height: 1500px;
margin-top: 50vh;
background-color: pink;
}
</style>
</head>
<body>
<div class="scroll-one">1</div>
<div class="scroll-two">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
<img src="./images/logo.png" data-src="./images/head.png" alt="" srcset="">
</div>
<script src="./index.js"></script>
</body>
</html>
let observer = new IntersectionObserver((entries) => {
entries.forEach((item) => {
if (item.isIntersecting) {
item.target.src = item.target.dataset.src;
// 替换成功后,停止观察该dom
observer.unobserve(item.target);
}
})
}, {
root: null
})
let one = document.querySelector('.scroll-one')
let two = document.querySelector('.scroll-two')
let images = document.querySelectorAll('.scroll-two img')
images.forEach(image => {
observer.observe(image)
})
场景应用·视频加载
下面是一个视频元素,希望它完全进入视口的时候自动播放,离开视口的时候自动暂停。
<video src="foo.mp4" controls=""></video>
let video = document.querySelector('video');
let isPaused = false;
let observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.intersectionRatio != 1 && !video.paused) {
video.pause();
isPaused = true;
} else if (isPaused) {
video.play();
isPaused=false;
}
});
}, {threshold: 1});
observer.observe(video);
上面代码中,IntersectionObserver()
的第二个参数是配置对象,它的threshold
属性等于1,即目标元素完全可见时触发回调函数。
参考链接
版权声明
本文系作者 @黄粱一梦 转载请注明出处,文中若有转载的以及参考文章地址也需注明。\(^o^)/~