大白话详解Intersection Observer API
昨日我写了Vue2 中自定义图片懒加载指令这篇博客,文章数据很好,阅览量能够上千,对于我这个刚写博客一周的新博主来说,是何等的荣幸。
所以在此我要感谢一切的读者与这个咱们庭,是你们肯定了我,让我有了学习和写博客的动力。
那现在就来更新今天的文章吧,持续连续昨日的文章,昨日的文章有朋友在谈论区推荐了Intersection Observer API
来完成图片懒加载,那这篇博客我先介绍一下这 API,但这 API 兼容性一般,且彻底不兼容 IE,咱们在实践项目中谨慎运用。
但在介绍Intersection Observer API之前,首要要先了解别的三个知识点,分别是 IntersectionObserver()结构器,IntersectionObserverEntry 方针与IntersectionObserverEntry 方针。
他们之前的联系比较复杂,咱们能够先看看这个整体联系图,以及他们的参数、特点与办法。
1.Intersection Observer API 的根本介绍
Intersection Observer API
供给了一种异步检测方针元素与祖先元素或视口(可统称为根元素)相交状况改变的办法。
-
留意点:
由于该 API 是异步的,它不会跟着方针元素的翻滚同步触发,而
IntersectionObserver API
是通过requestIdleCallback()完成,即只有浏览器空闲下来,才会执行调查器。这意味着这个调查器的优先级非常低。
1.1 Intersection Observer API 出现的原因
由于在如今网页开发的过程中,常常需求判别某个元素是否进入了”视口”(viewport),即用户能不能看到它。
面对这种相交检测的使命时,曩昔咱们通常会运用Element.getBoundingClientRect()
等办法来获取相关元素的方位信息,而且还会用到事情监听。
然而事情监听和调用Element.getBoundingClientRect()
等 API 都是运转在主线程,因而频频触发、调用会造成功能问题,而且这种检测办法运用起来比较繁琐。
因而官方就提出了Intersection Observer API
,该 API 的出现就是为了高效的处理以下两大类问题:
- 某个元素是否可见,如:
- 图片懒加载——当图片翻滚到可见时才进行加载
- 内容无限翻滚——当用户翻滚到接近底部时直接加载更多,而无需翻页,给用户一种网页能够无限翻滚的错觉
- 两个元素是否相交,如:
- 检测广告的曝光状况——为了核算广告收益,需求知道广告元素的曝光状况
- 在用户看见某个区域时执行使命或播放动画
Intersection Observer API
会注册一个回调函数,只会在以下两种状况触发:
- 方针元素进入或退出根元素
-
穿插比达到阈值时,补充点:
- 但是该 API 无法供给堆叠的像素个数或详细哪个像素堆叠,只能设置阈值来进行操控回调函数的调用。
这样,浏览器的主线程就不用在监听元素是否相交,而且IntersectionObserver API
是异步进行检测的,也不会占用主线程的资源,从而功能上得到了提升。
1.2 Intersection observer 的重要概念
Intersection observer API 有以下五个重要的概念:
- 方针(target)元素 — 咱们要监听的元素
-
根(root)元素 — 协助咱们判别方针元素是否契合条件的元素
以下两种状况根元素会默以为尖端文档的视口(一般为 html)。
- 方针元素不是可翻滚元素的子孙且不传值时
- 指定根元素为 null
- 穿插比(intersection ratio)—方针元素与根根的交集相对于方针元素百分比的表明(取值规模 0.0-1.0)。
- 阈值(threshold) — 回调函数触发的条件。
- 回调函数(callback) — 为该 API 装备的函数,会在设定的条件下触发。
2.IntersectionObserver()结构器
IntersectionObserver()
结构器用于创立一个 IntersectionObserver 方针,并会将该对像进行放回。
该结构器函数的装备参数如下图所示:
其语法如下:
var observer = new IntersectionObserver(callback[, options]);
2.1 IntersectionObserver()结构器的参数与回来值
首要咱们先了解一下IntersectionObserver()
结构器的参数,其参数有:
-
callback(必选参数) — 当穿插比超越指定阈值触发回调函数,此函数可接受两个参数:
-
entries
— 由IntersectionObserverEntry
方针组成的数组 但每个被触发的阈值,都或多或少与指定阈值有误差。 -
observer
— 回来被调用的IntersectionObserver
实例。
-
-
options(可选参数) — 用于装备回调函数触发的条件,其参数下还有三个子参数:
-
root
— 指定根元素。用于查看方针的可见性。默以为浏览器视口。- 假如指定为 null,也为浏览器视口。
- 有必要是方针元素的父级元素。
-
rootMargin
— 根元素的扩缩边距。其传值形式与 CSS 中 margin 相同,用于操控根元素每一边的扩缩(单位为 px 或%),从而操控核算根元素和方针元素的交集的区域规模,默许值为 0。 -
threshold
— 阈值,回调函数触发的条件。取值规模为 0.0-1.0,默许值为 0.0。- 当传入数值类型时,只会触发一次。
- 当传入数组类型时,可触发多次。
- 如:[0,0.25,0.5,0.75,1]表明方针元素在跟元素的可见程度每多 25% 就执行一次回调
-
-
该函数的回来值: 一个新的
IntersectionObserver
对像。- 该方针会依照设定的阈值来监听方针元素。
- 调用自身的
observe()
办法开端对方针元素进行监听。
2.2 IntersectionObserver()结构器的根本语法与反常信息
运用 IntersectionObserver()结构器创立 IntersectionObserver 方针并进行监听的语法如代码下所示:
let options = {
root: document.querySelector("#root"), //根元素
rootMargin: "0px", //传值形式相似于css的margin 传一个值则四个边都为0
threshold: 0, //触发条件 表明方针元素刚进入根元素时触发
};
//IntersectionObserver方针
let observer = new IntersectionObserver(callback, options);
let target = document.querySelector("#target"); //方针元素
observer.observe(target); //开端监听该方针元素
- 两种反常类型:
- SyntaxError — 指定的 rootMargin 不存在或不契合语法。
- RangeError — 一个或多个阈值超出了 0.0 到 1.0 的规模。
3.IntersectionObserver 方针
IntersectionObserver 接口(从属于Intersection Observer API
)供给了一种异步调查方针元素与根元素 穿插状况的办法。
当 IntersectionObserver 方针被创立时,就会被指定所监听的根元素、阀值等信息。一旦 IntersectionObserver 被创立后就无法更改其指定信息。
- 所以一个给定的调查者方针只能用来监听可见区域的特定改变值;当然你也能够在同一个调查者方针中装备监听多个方针元素。
该方针的特点与办法如下图所示:
3.1 IntersectionObserver 方针的特点与办法
3.1.1 三个特点
该对像的三个特点与IntersectionObserver()
结构器的 options 参数相似,而且这三个特点都只能读取操作,不能进行更改。
特点 | 阐明 | 默许值 |
---|---|---|
root | 指定根元素。假如传值为 null,则为尖端文档的视窗。 | 尖端文档的视口(一般为 html) |
rootMargin | 根元素的扩缩边距。其传值形式与 CSS 中 margin 相同,用于操控根元素每一边的扩缩(单位为 px 或%),从而操控核算根元素和方针元素的交集的区域规模。单位为 px 或%。默 | “0px 0px 0px 0px” |
thresholds | 一个包含阈值的数组,并按升序摆放,列表中的每个阈值都是监听方针的穿插区域与边界区域的比率。当监听方针的任何阈值被越过期,都会触发回调函数。 | 0 |
3.1.2 四个办法
该方针的四个办法如下表:
办法 | 阐明 |
---|---|
observe(target) | 开端监听指定方针元素 |
unobserve(target) | 中止监听指定的方针元素 |
takeRecords() | 回来一切调查方针的 IntersectionObserverEntry 方针数组 |
disconnect() | 使 IntersectionObserver 方针中止全部监听作业 |
4. IntersectionObserverEntry 方针
IntersectionObserverEntry
接口(从属于 Intersection Observer API)描绘了方针元素与其根元素容器在某一特定过渡时刻的穿插状况。
IntersectionObserverEntry
对像数组作为entries
参数传递给IntersectionObserver
对像的回调函数中; 此外,这方针数组只能通过调用IntersectionObserver.takeRecords()
来获取。
该方针的主要特点如下图所示:
4.1 IntersectionObserverEntry 方针的特点
IntersectionObserverEntry 方针的七个特点都是只读特点,如下表所示:
特点 | 阐明 |
---|---|
target | 回来方针元素,表明现在该方针正监听的元素 |
isIntersecting | 回来一个布尔值,方针元素刚出现在根元素可视区时回来 true;方针元素从根元素可视区消失回来 false;以上两种状况都会触发 callback 函数 |
boundingClientRect | 回来方针元素的矩形区域的信息,回来结果与element.getBoundingClientRect()相同 |
rootBounds | 回来根元素的矩形区域的信息,getBoundingClientRect()办法的回来值,假如没有根元素(即直接相对于视口翻滚),则回来 null |
intersectionRect | 回来方针元素与视口(或根元素)的穿插区域的信息 |
intersectionRatio | 回来方针元素的可见份额,即intersectionRect 占boundingClientRect 的份额,彻底可见时为 1,彻底不行见时小于等于 0 |
time | 回来一个记载从IntersectionObserver 的时刻原点到穿插被触发的时刻的时刻戳 |
5. Intersection Observer API 的兼容性
该 API 的兼容性如下:
详情咱们可参阅CAN I USE – intersectionobserver。
6. Intersection Observer API 的简单案列
咱们能够在自己电脑运转一下下面的代码,会有更深的了解。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.container > div {
margin: 5px auto;
width: 100px;
height: 100px;
outline: 1px solid red;
}
</style>
</head>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
<div class="item">11</div>
<div class="item">12</div>
<div class="item">13</div>
<div class="item">14</div>
<div class="item">15</div>
</div>
<script>
//io 为 IntersectionObserver方针 - 由IntersectionObserver()结构器创立
var io = new IntersectionObserver((entries) => {
//entries 为 IntersectionObserverEntry对像数组
entries.forEach((item) => {
//item 为 IntersectionObserverEntry对像
// isIntersecting是一个Boolean值,判别方针元素当时是否可见
if (item.isIntersecting) {
//div 可见时 进行相关操作
console.log(item.target.innerText);
io.unobserve(item.target); //中止监听该div DOM节点
}
});
}); //不传options参数,默许根元素为浏览器视口
const divArr = [...document.querySelectorAll(".item")];
divArr.forEach((div) => io.observe(div)); // 遍历监听一切div DOM节点
</script>
</body>
</html>
我已在 Vue2 运用Intersection Observer API
完成了图片懒加载作用哦,咱们能够去看看。Vue2 中自定义图片懒加载指令 2.0
参阅博客
- MDN – Intersection Observer API
- MDN – IntersectionObserver.IntersectionObserver()
- MDN – Intersection Observer
- MDN – IntersectionObserverEntry
- 超好用的 API 之 IntersectionObserver
- 阮一峰 – IntersectionObserver API 运用教程
结语
这是我现在所了解的知识面中最好的解答,当然也有或许存在一定的误区。
所以假如对本文存在疑问,能够在谈论区留言,我会及时回复的,欢迎咱们指出文中的错误观点。
最后码字不易,觉得有协助的朋友点赞、保藏、重视走一波。