1 定义
Intersection Observer API提供了一种异步观察目标元素与祖先元素或顶级文档viewport的交集中的变化的方法。
说白了,就是判断一个元素与其父元素(或浏览器视窗)的重叠情况。
2 用法
var observer = new IntersectionObserver(callback, options);
2.1 options
先谈谈options,options是一个对象,有三个字段
-
root
指定根(root)元素,用于检查目标的可见性。必须是目标元素的父级元素。如果未指定或者为null,则默认为浏览器视窗。 -
rootMargin
root元素的外边距。类似于css中的 margin 属性。但我觉得像是padding属性,它会扩大root的判断范围。比如padding是20px,那么root的范围上下左右,会扩大20px,也就是说,判定范围变大了。 -
threshold
可以是单一的number也可以是number数组,target元素和root元素相交程度达到该值的时候IntersectionObserver注册的回调函数将会被执行。该值取0.0到1.0之间,代表交叉的比率。
2.2 callback
var callback = function(entries, observer) {
entries.forEach(entry => {
// Each entry describes an intersection change for one observed
// target element:
// entry.boundingClientRect
// entry.intersectionRatio
// entry.intersectionRect
// entry.isIntersecting
// entry.rootBounds
// entry.target
// entry.time
});
};
对于每一个entry有如下属性
- boundingClientRect 目标元素的矩形信息
- intersectionRatio 相交区域和目标元素的比例值
- intersectionRect/boundingClientRect 不可见时小于等于0
- intersectionRect 目标元素和视窗(根)相交的矩形信息 可以称为相交区域
- isIntersecting 目标元素当前是否可见 Boolean值 可见为true
- rootBounds 根元素的矩形信息,没有指定根元素就是当前视窗的矩形信息
- target 观察的目标元素
- time 返回一个记录从IntersectionObserver的时间到交叉被触发的时间的时间戳
3 lazyload懒加载demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
img {
height: 500px;
}
</style>
</head>
<body>
<div>
<img src="../asset/unknown.png" alt="x" id="1">
</div>
<div>
<img src="../asset/unknown.png" alt="x" id="2">
</div>
<div>
<img src="../asset/unknown.png" alt="x" id="3">
</div>
<div>
<img src="../asset/unknown.png" alt="x" id="4">
</div>
<div>
<img src="../asset/unknown.png" alt="x" id="5">
</div>
<script>
const URL = '../asset/loader.jpg'
let imgs = document.querySelectorAll('img');
let observer = new IntersectionObserver((entries)=>{
// console.log(entries);
// entry is a <img />
entries.forEach((entry) => {
if (entry.isIntersecting === true) {
console.log(entry);
entry.target.src = URL;
}
})
},
{
threshold: 0.2
})
imgs.forEach((e) => {
// e is a <img />
observer.observe(e);
})
</script>
</body>
</html>