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时,会执行指定的回调函数。
  • 参数optionIntersectionObserver构造函数的第二个参数是一个配置对象,其可以设置以下属性:
    • 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,表示toprightbottomleft四个方向的值。
  • 属性IntersectionObserver.root只读,所监听对象的具体祖先元素element,如果未传入值或值为null,则默认使用顶级文档的视窗。
  • 属性IntersectionObserver.rootMargin只读,计算交叉时添加到根root边界盒bounding box的矩形偏移量,可以有效的缩小或扩大根的判定范围从而满足计算需要,此属性返回的值可能与调用构造函数时指定的值不同,因此可能需要更改该值,以匹配内部要求,所有的偏移量均可用像素pixelpx或百分比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:目标元素的可见比例,即intersectionRectboundingClientRect的比例,完全可见时为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">&nbsp;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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/611027.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【CCF-CSP】202403-3 化学方程式配平

输入格式&#xff1a; 从标准输入读入数据。 输入的第一行包含一个正整数 n&#xff0c;表示需要判断的化学方程式的个数。 接下来的 n 行&#xff0c;每行描述了一个需要被配平的化学方程式。包含空格分隔的一个正整数和全部涉及物质的化学式。其中&#xff0c;正整数 m 表…

洗地机挑选有哪些要点?附618热门洗地机推荐

随着科技的不断发展&#xff0c;洗地机已经成为了人们家庭里必备的清洁家电了&#xff0c;它可以让我们高效的完成深度清洁的工作&#xff0c;让我们从繁重的家务劳动中解放出来&#xff0c;享受更轻松舒适的生活。那么我们如何在众多洗地机品牌中找到适合自己的产品呢&#xf…

win10无法被远程桌面连接,Win10系统无法被远程桌面连接的原因有哪些

win10无法被远程桌面连接&#xff0c;Win10系统无法被远程桌面连接的原因有哪些&#xff1f; 先&#xff0c;我们需要明确Win10系统无法被远程桌面连接的可能原因。其中&#xff0c;最常见的原因包括&#xff1a;远程桌面功能未启用、网络连接问题、防火墙或安全软件设置不当、…

通俗的理解网关的概念的用途(一)

网关这个概念最早使用于网络&#xff0c;但在当今的智能设备/产品界中&#xff0c;硬生生的被产品人也搞出来一个“网关”的概念&#xff0c;这让早期的咱们这些只知道网络中的网关的人&#xff0c;听得稀里糊涂的。比如智能门锁、安防摄像头等&#xff0c;在产品的使用和介绍中…

node报错——解决Error: error:0308010C:digital envelope routines::unsupported——亲测可用

今天在打包vue2项目时&#xff0c;遇到一个报错&#xff1a; 最关键的代码如下&#xff1a; Error: error:0308010C:digital envelope routines::unsupportedat new Hash (node:internal/crypto/hash:80:19)百度后发现是node版本的问题。 在昨天我确实操作了一下node&…

C++——命名空间

c ——命名空间 前言一.命名空间命名空间的进一步拓展 二.io流特性 前言 ** 好久不见&#xff0c;甚是想念~今天我们讲解的是关于c命名空间的一些知识点&#xff0c;这只是开胃小菜哦&#xff0c;期待我们后面更深入知识的灵魂碰撞吧 ** 一.命名空间 怎么形容呢~命名空间出现…

网络编程--tcp三次握手四次挥手

1、三次握手 &#xff08;1&#xff09;三次握手的详述 首先Client端发送连接请求报文&#xff0c;Server段接受连接后回复ACK报文&#xff0c;并为这次连接分配资源。Client端接收到ACK报文后也向Server段发生ACK报文&#xff0c;并分配资源&#xff0c;这样TCP连接就建立了。…

数据结构--顺序表和链表的区别

顺序表和链表之间各有优劣&#xff0c;我们不能以偏概全&#xff0c;所以我们在使用时要关注任务的注重点&#xff0c;以此来确定我们要使用两者中的哪一个。 不同点&#xff1a; 存储空间上&#xff1a; 顺序表在物理结构上是一定连续的&#xff0c;而链表(这里以带头双向循环…

DS:顺序表、单链表的相关OJ题训练(2)

欢迎各位来到 Harper.Lee 的学习世界&#xff01; 博主主页传送门&#xff1a;Harper.Lee的博客主页 想要一起进步的uu欢迎来后台找我哦&#xff01; 一、力扣--141. 环形链表 题目描述&#xff1a;给你一个链表的头节点 head &#xff0c;判断链表中是否有环。如果链表中有某个…

Web前端开发 小实训(三) 商品秒杀小练习

学生能够在本次实训中完成商品秒杀页面的基本逻辑 任务要求 能够实现某一个商品的秒杀&#xff0c;在倒计时结束后不再进行秒杀。 操作步骤 1、打开预设好的页面 <html><head><meta charset"utf-8"><title>秒杀</title><link …

vue + element-plus 开发中遇到的问题

1.问题之路由守卫 初写路由守卫&#xff0c;对于next()的理解不是很透彻&#xff0c;就想着都放行&#xff0c;不然看不到效果&#xff0c;结果控制台出现了警告&#xff0c;想着报黄的问题就不是问题&#xff0c;但仔细一看发现他说&#xff0c;如果再生产阶段就会失败&#x…

【问题分析】锁屏界面调起google语音助手后壁纸不可见【Android 14】

1 问题描述 为系统和锁屏分别设置两张不同的壁纸&#xff0c;然后在锁屏界面长按Power调起google语音助手后&#xff0c;有时候会出现壁纸不可见的情况&#xff0c;如以下截图所示&#xff1a; 有的时候又是正常的&#xff0c;但显示的也是系统壁纸&#xff0c;并非是锁屏壁纸…

【用文本生成歌声】Learn2Sing 2.0——歌声转换算法及梅尔频谱详解

一. 频谱图与梅尔谱图的介绍 频谱图&#xff1a;频谱图可以理解为一堆垂直堆叠在一起的快速傅里叶变换结果。 1.1 信号 在进入频谱图模块之前&#xff0c;首先我们需要了解信号是什么。 信号就是某一特定量随时间变化&#xff0c;对于音频来说&#xff0c;这个特定的变化量就…

韩顺平0基础学Java——第8天

p155-168 数组&#xff08;第六章&#xff09; 数组可以存放多个同一类型的数据&#xff0c;数组也是一种数据类型&#xff08;引用类型&#xff09;。 即&#xff0c;数组就是一组数据~ 例&#xff1a;double [] hens {1,2,3,4,5,6}; 新建了一组鸡&#xff0c;里面有6个。…

代码随想录算法训练营第36期DAY18

DAY18 二叉树的层序遍历 102二叉树的层序遍历 “队列先进先出&#xff0c;符合一层一层遍历的逻辑&#xff0c;而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。” 二叉树层序遍历模版&#xff1a; /** * Definition for a binary tree node. * struct TreeNode { *…

PostgreSQL的学习心得和知识总结(一百四十二)|深入理解PostgreSQL数据库数据库之 Continuous Integration

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

办公技巧之合集文档 拆分_word

问题 如何将文档合集拆分为单独文档。 操作步骤 软件 word 365 原理简述&#xff1a; 在 word 大纲视图下&#xff0c;通过一级标题确定子文档范围&#xff0c;然后导出即可。 文档结构 从下图可见&#xff0c;文档结构为已建立大纲级别的文档&#xff0c;如果没有建立&a…

每日一题——力扣27. 移除元素(举一反三)

题目链接&#xff1a;https://leetcode.cn/problems/remove-element/description/ 菜鸡写法&#xff1a; // 函数定义&#xff0c;移除数组nums中所有值为val的元素&#xff0c;并返回新的数组长度 int removeElement(int* nums, int numsSize, int val) {// 如果数组长度为…

Steam游戏搬砖,不说破万,月入5K没问题

steam游戏搬砖项目的玩法就是打汇率差&#xff0c;在steam平台购买道具&#xff0c;挂在网易buff上出售&#xff0c;通过汇率差盈利。一天交易几百美金的道具&#xff0c;大概能搞到200块左右的利润&#xff0c;而且平台是支持这样交易的&#xff0c;还很稳定。目前最主流的游戏…

设计模式1——初步认识篇

设计模式1——初步认识篇 一、先让我们浅聊一下面向对象和设计模式。 说起设计模式&#xff0c;我第一次听到它&#xff0c;是在学习面向对象的时候。那么什么是面向对象&#xff0c;什么是设计模式&#xff0c;而且设计模式和面向对象又有什么关系呢&#xff1f; 1、什么是面…
最新文章