IntersectionObserver对象
IntersectionObserver对象
IntersectionObserver对象,从属于Intersection Observer API,提供了一种异步观察目标元素与其祖先元素或顶级文档视窗viewport交叉状态的方法,祖先元素与视窗viewport被称为根root,也就是说IntersectionObserver API,可以自动观察元素是否可见,由于可见visible的本质是,目标元素与视口产生一个交叉区,所以这个API叫做交叉观察器,兼容性https://caniuse.com/?search=IntersectionObserver。
描述
IntersectionObserver解决了一个长期以来Web的问题,观察元素是否可见,这个可见visible的本质是,目标元素与视口产生一个交叉区,所以这个API叫做交叉观察器。
要检测一个元素是否可见或者两个元素是否相交并不容易,很多解决办法不可靠或性能很差。现在很多需求下都需要用到相交检测,例如图片懒加载、内容无限滚动、检测元素的曝光情况、可视区域播放动画等等,相交检测通常要用到onscroll事件监听,并且可能需要频繁调用Element.getBoundingClientRect()等方法以获取相关元素的边界信息,事件监听和调用Element.getBoundingClientRect都是在主线程上运行,因此频繁触发、调用可能会造成性能问题,这种检测方法极其怪异且不优雅。
Intersection Observer API会注册一个回调函数,每当被监视的元素进入或者退出另外一个元素时或viewport,或者两个元素的相交部分大小发生变化时,该回调方法会被触发执行,这样网站的主线程不需要再为了监听元素相交而辛苦劳作,浏览器会自行优化元素相交管理,注意Intersection Observer API无法提供重叠的像素个数或者具体哪个像素重叠,他的更常见的使用方式是当两个元素相交比例在N%左右时,触发回调,以执行某些逻辑。
const io = new IntersectionObserver(callback, option);
// 开始观察
io.observe(document.getElementById("example"));
// 停止观察
io.unobserve(element);
// 关闭观察器
io.disconnect();
- 参数
callback,创建一个新的IntersectionObserver对象后,当其监听到目标元素的可见部分穿过了一个或多个阈thresholds时,会执行指定的回调函数。 - 参数
option,IntersectionObserver构造函数的第二个参数是一个配置对象,其可以设置以下属性:threshold属性决定了什么时候触发回调函数,它是一个数组,每个成员都是一个门槛值,默认为[0],即交叉比例intersectionRatio达到0时触发回调函数,用户可以自定义这个数组,比如[0, 0.25, 0.5, 0.75, 1]就表示当目标元素0%、25%、50%、75%、100%可见时,会触发回调函数。root属性指定了目标元素所在的容器节点即根元素,目标元素不仅会随着窗口滚动,还会在容器里面滚动,比如在iframe窗口里滚动,这样就需要设置root属性,注意,容器元素必须是目标元素的祖先节点。rootMargin属性定义根元素的margin,用来扩展或缩小rootBounds这个矩形的大小,从而影响intersectionRect交叉区域的大小,它使用CSS的定义方法,比如10px 20px 30px 40px,表示top、right、bottom和left四个方向的值。
- 属性
IntersectionObserver.root只读,所监听对象的具体祖先元素element,如果未传入值或值为null,则默认使用顶级文档的视窗。 - 属性
IntersectionObserver.rootMargin只读,计算交叉时添加到根root边界盒bounding box的矩形偏移量,可以有效的缩小或扩大根的判定范围从而满足计算需要,此属性返回的值可能与调用构造函数时指定的值不同,因此可能需要更改该值,以匹配内部要求,所有的偏移量均可用像素pixel、px或百分比percentage、%来表达,默认值为0px 0px 0px 0px。 - 属性
IntersectionObserver.thresholds只读,一个包含阈值的列表,按升序排列,列表中的每个阈值都是监听对象的交叉区域与边界区域的比率,当监听对象的任何阈值被越过时,都会生成一个通知Notification,如果构造器未传入值,则默认值为0。 - 方法
IntersectionObserver.disconnect(),使IntersectionObserver对象停止监听工作。 - 方法
IntersectionObserver.observe(),使IntersectionObserver开始监听一个目标元素。 - 方法
IntersectionObserver.takeRecords(),返回所有观察目标的IntersectionObserverEntry对象数组。 - 方法
IntersectionObserver.unobserve(),使IntersectionObserver停止监听特定目标元素。
此外当执行callback函数时,会传递一个IntersectionObserverEntry对象参数,其提供的信息如下。
time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒。target:被观察的目标元素,是一个DOM节点对象。rootBounds:根元素的矩形区域的信息,是getBoundingClientRect方法的返回值,如果没有根元素即直接相对于视口滚动,则返回null。boundingClientRect:目标元素的矩形区域的信息。intersectionRect:目标元素与视口或根元素的交叉区域的信息。intersectionRatio:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0。
应用
实现一个使用IntersectionObserver的简单示例,两个方块分别可以演示方块1是否在屏幕可见区域内以及方块2是否在方块1的相对可见交叉区域内,另外可以使用IntersectionObserver可以进行首屏渲染的优化,可以参考https://github.com/WindrunnerMax/EveryDay/blob/master/Vue/Vue%E9%A6%96%E5%B1%8F%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E7%BB%84%E4%BB%B6.md。
<!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>
body{
margin: 0;
padding: 0;
height: 100vh;
width: 100vw;
overflow-x: hidden;
}
.flex{
display: flex;
}
.top-fixed{
top: 0;
position: fixed;
}
.placeholder1{
width: 100%;
}
#box1{
height: 200px;
overflow-y: auto;
border: 1px solid #aaa;
width: 60%;
}
.box1-placeholder{
height: 105vh;
}
#box2{
height: 100px;
background-color: blue;
margin-top: 300px;
width: 60%;
}
.box2-placeholder{
height: 205px;
}
</style>
</head>
<body>
<section class="flex top-fixed">
<div class="flex">BOX1:</div>
<div class="flex" id="box1-status">invisible</div>
<div class="flex"> BOX2:</div>
<div class="flex" id="box2-status">invisible</div>
</section>
<div class="box1-placeholder"></div>
<div id="box1">
<div class="box2-placeholder"></div>
<div id="box2"></div>
<div class="box2-placeholder"></div>
</div>
<div class="box1-placeholder"></div>
</body>
<script>
(function(){
const box1 = document.querySelector("#box1");
const box2 = document.querySelector("#box2");
const box1Status = document.querySelector("#box1-status");
const box2Status = document.querySelector("#box2-status");
const box1Observer = new IntersectionObserver(entries => {
entries.forEach(item => {
// `intersectionRatio`为目标元素的可见比例,大于`0`代表可见
if (item.intersectionRatio > 0) {
box1Status.innerText = "visible";
}else{
box1Status.innerText = "invisible";
}
});
}, {root: document});
const box2Observer = new IntersectionObserver(entries => {
entries.forEach(item => {
// `intersectionRatio`为目标元素的可见比例,大于`0`代表可见
if (item.intersectionRatio > 0) {
box2Status.innerText = "visible";
}else{
box2Status.innerText = "invisible";
}
});
}, {root: box1});
box1Observer.observe(box1);
box2Observer.observe(box2);
})();
</script>
</html>
每日一题
https://github.com/WindrunnerMax/EveryDay
参考
https://www.jianshu.com/p/eadd83d794c8
https://www.ruanyifeng.com/blog/2016/11/intersectionobserver_api.html
https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver
IntersectionObserver对象的更多相关文章
- js滚动及可视区域的相关的操作
element.getBoundingClientRect 判断指定元素相对于页面可视窗口的位置信息,通常结合windows.onScroll方法使用,当element.getBoundingClie ...
- 原生js - 两种图片懒加载实现原理
目前图片懒加载的方式主要有两种: 1.利用getBoundingClientRectAPI得到当前元素与视窗的距离来判断 2.利用h5的新API IntersectionObserver 来实现 ge ...
- 微信小程序实现滚动视频自动播放(未优化)
先看看大概效果 1.首先需要了解微信API: wx.createIntersectionObserver(Object component, Object options) 创建并返 ...
- Vue首屏性能优化组件
Vue首屏性能优化组件 简单实现一个Vue首屏性能优化组件,现代化浏览器提供了很多新接口,在不考虑IE兼容性的情况下,这些接口可以很大程度上减少编写代码的工作量以及做一些性能优化方面的事情,当然为了考 ...
- IntersectionObserver API
温馨提示:本文目前仅适用于在 Chrome 51 及以上中浏览. 2016.11.1 追加,Firefox 52 也已经实现. 2016.11.29 追加,Firefox 的人担心目前规范不够稳定,未 ...
- 使用IntersectionObserver更高效的监视某个页面元素是否进入了可见窗口
比如说,你想跟踪 DOM 树里的一个元素,当它进入可见窗口时得到通知. 也许想实现即时延迟加载图片功能,或者你需要知道用户是否真的在看一个广告 banner. 你可以通过绑定 scroll 事件或者用 ...
- IntersectionObserver API 使用教程
转载:原文地址:http://www.ruanyifeng.com/blog/2016/11/intersectionobserver_api.html 网页开发时,常常需要了解某个元素是否进入了&q ...
- IntersectionObserver简介
写在前面 在移动端,有个很重要的概念,叫做懒加载,适用于一些图片资源特别多,ajax数据特别多的页面中,经常会有动态加载数据的场景中,这个时候,我们通常是使用监听scroll或者使用setInterv ...
- IntersectionObserver
创建对象 var io = new IntersectionObserver(callback, option); IntersectionObserver是浏览器原生提供的构造函数,接受两个参数:c ...
- IntersectionObserver API,观察元素是否进入了可视区域
网页开发时,常常需要了解某个元素是否进入了"视口"(viewport),即用户能不能看到它. 上图的绿色方块不断滚动,顶部会提示它的可见性. 传统的实现方法是,监听到scroll事 ...
随机推荐
- 例2.6 设计一个高效的算法,从顺序表L中删除所有值为x的元素,要求时间复杂度为0(n)空间复杂度为0(1)。
1.题目 例2.6 设计一个高效的算法,从顺序表L中删除所有值为x的元素,要求时间复杂度为0(n)空间复杂度为0(1). 2.算法思想 3.代码 void DeleteX(SeqList LA, Se ...
- [转帖]Kubernetes1.25.6部署文档 使用cri-docker部署K8s1.25.6
https://zhuanlan.zhihu.com/p/600808149 本文档将通过kubeadm+docker部署K8s集群,本次集群使用的容器运行工具为docker,K8s的容器运行工具也可 ...
- [转帖]构建 TiFlash 副本
https://docs.pingcap.com/zh/tidb/stable/create-tiflash-replicas#%E6%8C%89%E8%A1%A8%E6%9E%84%E5%BB%BA ...
- [转帖]一口气看完45个寄存器,CPU核心技术大揭秘
https://www.cnblogs.com/xuanyuan/p/13850548.html 序言 前段时间,我连续写了十来篇CPU底层系列技术故事文章,有不少读者私信我让我写一下CPU的寄存器. ...
- JVM内存配置的再次思考
JVM内存配置的再次思考 摘要 最近研究过不少内存分配相关的处理 今天晚上突然感觉还不是非常系统. 还是想能够细致的在学习一下. 希望能够慢慢的拾遗,提高自己 操作系统内存的使用情况 本文主要想思考l ...
- [转帖] Linux查看日志文件写入速度的4种方法
https://www.cnblogs.com/codelogs/p/16365448.html 简介# 有时,我们需要查看某个文件的增长速度,如日志文件,以此来感受系统的负载情况,因为一般情况下,日 ...
- Linux下PG数据库计划任务定期备份恢复的方法
注意事项 PG数据库需要注意的一点是需要安装OSSP-UUID的组件才能使用. 本次使用最除了冷备之外 最简单的 pg_dump和pg_restore的操作 的方式来进行处理 务必定期演练保证数据备份 ...
- SAP标准附件-GOS(generic object service)
标准附件功能显示需要用户是 A类型 对话用户 本文介绍一个Public Class :CL_GOS_DOCUMENT_SERVICE 该类包含了创建附件,注释,URL,个人注释等方法,这些方法中都会涉 ...
- ElasticSearch降本增效常见的方法 | 京东云技术团队
Elasticsearch在db_ranking 的排名不断上升,其在存储领域已经蔚然成风且占有非常重要的地位. 随着Elasticsearch越来越受欢迎,企业花费在ES建设上的成本自然也不少.那如 ...
- 行云部署成长之路--慢SQL优化之旅 | 京东云技术团队
当项目的SQL查询慢得像蜗牛爬行时,用户的耐心也在一点点被消耗,作为研发,我们可不想看到这样的事.这篇文章将结合行云部署项目的实践经验,带你走进SQL优化的奇妙世界,一起探索如何让那些龟速的查询飞 ...