Intersection Observer API 帮你搞定前端滚动问题

news2024/11/23 0:52:40

前言

当我们在做需求时,可能经常会遇到很多跟页面的滚动有关的需求。例如

  • 图片的懒加载:我们希望只加载用户当前视图窗口的图片,而未进入到视图窗口的图片,只有在进入到视图窗口时才进行加载,以提高页面响应速度,从而改善用户体验。

  • 无限滚动:我们希望在一个页面在不断下拉的过程中,不断的加载新的内容,而无需进行页面跳转,类似于Vue、React等框架中的虚拟DOM的思想,以提升用户体验。

  • 根据元素位置需求渲染元素:根据元素在视图窗口中的不同位置去进行一些或动画效果或者样式的改变。

当我们拿到这些需求的时候,可能大家最先想到的实现方法都是使用scroll监听,通常过不断轮询目标元素的位置信息,然后计算是否符合特定条件,来进行操作DON。但是,这种不断轮询方式会在JavaScript的主线程中不断执行,导致性能的极大消耗,很容易就会造成页面的掉帧,从而严重影响用户体验,。

今天我们就来讲讲另一个更好的解决方案Intersection Observer API。它能够在帮助我们实现需求的同时,减少性能的消耗,从而提升用户体验。

动画.gif

## `Intersection Observer`交叉观察者。 > 官方定义: Intersection Observer是一个JavaScript API,用于异步监测目标元素与其祖先元素或视口的交叉情况。

通俗点说就是,Intersection Observer可以帮助我们监测一个元素是否进入或离开另一个元素或浏览器窗口的视口,并且可以精确到一个元素的可见比例

优点

  1. 性能强

    • 异步处理:相比于传统scroll事件监听的,Intersection Observer使用异步回调,避免了阻塞主线程,从而提高了性能。
    • 减少不必要的计算:相比于传统的频繁地检查元素的可见性,Intersection Observer只在元素的符合条件下才发生变化时的回调,
  2. 使用简单

    • 无需手动检测:使用Intersection Observer,不再需要我们手动编写大量代码来检测元素是否在视口中,在开发更加简单和可维护。
  3. 实时监测

    • 实时反馈:它能够即时响应元素的可见性变化,适用于需要实时反馈的交互效果。
  4. 精确度

    • 自定义阈值:我们可以手动的设置触发回调的阈值,可以更精确度的根据需求来触发回调。
  5. 跨浏览器兼容性

    • 兼容性好:Intersection Observer是标准的Web API,被主流浏览器支持,具有较好的跨浏览器兼容性。

image.png

用法

Intersection Observer API包括4部分:构造函数观察选项回调函数和一些方法

  1. 构造函数:IntersectionObserver

    构造函数用于创建Intersection Observer我们的实例,它接受两个参数:回调函数和观察选项。当被观察的元素和我们的窗口视图,或者别的元素的交叉状态满足我们设定的观察选项时,我们的回调函数就会被触发。

    const observer = new IntersectionObserver(callback, options);
    
  2. 观察选项(Options)

    观察选项是一个配置对象,用于指定我们的观察规则。它包括3个属性:

    • root:根元素,用于指定一个容器元素,设为null时会默认使用视口作为根元素。
    • rootMargin:根元素的边距范围,用像素或百分比表示,该属性值是用作 root 元素和 target 发生交集时候的计算交集的区域范围,用于扩大或缩小可视区域。
    • threshold:一个触发回调的阈值数组,表示目标元素的可见比例。

image.png

代码示例:

const options = {
root: document.querySelector('#container'), // 视口的根元素
rootMargin: '0px', // 例如 "10px 20px 30px 40px" (top, right, bottom, left)。
threshold: [0, 0.25, 0.5, 0.75, 1] //这里当目标元素的可见比例分别达到0%、25%、50%、75%和100%时,都会触发回调函数
};

  1. 回调函数(Callback Function)

    回调函数会在被观察的元素的交叉状态发生变化时被调用。它接收两个参数:entriesobserver

    • entries:一个Intersection Observer Entry对象的数组,每个Entry对象表示一个被观察元素与视口或根元素的交叉状态的信息。
    • observer:对观察器本身的引用,通常不需要使用。

    每个Entry对象包含以下信息:

    `target`:被观察的目标元素,即触发了交叉事件的元素。
    `time`:发生相交到相应的时间,毫秒。
    `rootBounds`:根元素矩形区域的信息,如果没有设置根元素则返回 null,图中蓝色部分区域。
    `boundingClientRect`:一个DOMRect对象,描述了目标元素的边界框,包括位置、大小等信息。,图中黑色边框的区域。
    `intersectionRect`:一个DOMRect对象,表示目标元素与视口或根元素的交叉区域的边界框,图中蓝色方块和粉红色方块相交的区域。
    `intersectionRatio`:一个介于0和1之间的值,表示目标元素的可见比例,0表示完全不可见,1表示完全可见。
    -  `isIntersecting`:一个布尔值,表示目标元素是否与视口或根元素发生交叉。
    

代码示例:

// 创建一个 Intersection Observer 实例
const observer = new IntersectionObserver(callback, options);

// 回调函数,处理相交事件
function callback(entries, observer) {
entries.forEach(entry => {
 const target = entry.target; // 被观察的目标元素
 const time = entry.time; // 发生相交的时间(毫秒)

 const rootBounds = entry.rootBounds; // 根元素的矩形区域信息
 const boundingClientRect = entry.boundingClientRect; // 目标元素的边界框信息
 const intersectionRect = entry.intersectionRect; // 目标元素与视口的交叉区域信息
 const intersectionRatio = entry.intersectionRatio; // 目标元素的可见比例
 const isIntersecting = entry.isIntersecting; // 目标元素是否与视口发生交叉

 // 打印这些信息
 console.log('目标元素:', target);
 console.log('发生相交的时间:', time);
 console.log('根元素矩形区域信息:', rootBounds);
 console.log('目标元素边界框信息:', boundingClientRect);
 console.log('交叉区域信息:', intersectionRect);
 console.log('可见比例:', intersectionRatio);
 console.log('是否相交:', isIntersecting);

 // 根据需要执行操作,例如加载图片或触发动画
 if (isIntersecting) {
   // 目标元素进入视口,执行相关操作
 } else {
   // 目标元素离开视口,执行其他操作
 }
});
}

// 启动观察
const targetElement = document.querySelector('#your-target-element'); // 选择要观察的目标元素
observer.observe(targetElement); // 开始观察目标元素

jcode

注意:

  • 我们注册的回调函数将在主线程中执行,因此我们应该尽量保持函数的执行速度。如果需要执行一些耗时或者会引起阻塞的操作,建议使用 Window.requestIdleCallback() 方法。

  • 在 Intersection Observer API 中,所有区域都被视为矩形。即使元素的形状不规则,它也会被看作包含该元素所有区域的最小矩形。同样,如果元素与视口的交集部分不是矩形,它也将被看作包含所有交集区域的最小矩形。

  1. 方法

    Intersection Observer实例还提供了一些方法,可以用于操作观察器的行为:

    • observe(target):将目标元素添加到观察器中,开始监测其交叉状态。
    • unobserve(target):停止监测特定目标元素的交叉状态。
    • disconnect():停止监测所有目标元素的交叉状态,可以在不需要观察器时使用。

    示例:

    const observer = new IntersectionObserver(callback, options);
    observer.observe(document.querySelector('#element'));
    observer.unobserve(document.querySelector('#element'));
    observer.disconnect();
    

代码示例

以下是一个简单的Intersection Observer示例,它会监测目标元素何时进入视口并改变其背景颜色:

<div id="target" style="height: 200px; background-color: lightblue;"></div>

<script>
  const target = document.querySelector('#target');
  const options = {
    root: null,// 根元素,通常使用视口,可以设为null
    rootMargin: '0px', // 根元素的边距,用于扩展或缩小可视区域
    threshold: 0.5 // 触发回调的阈值,0表示完全不可见,1表示完全可见
  };

  const callback = (entries, observer) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        target.style.backgroundColor = 'lightgreen';
      } else {
        target.style.backgroundColor = 'lightblue';
      }
    });
  };

  const observer = new IntersectionObserver(callback, options);
  
  //将观察器绑定到目标元素上,以开始监测可见性变化。
  observer.observe(target);
</script>

jcode

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

简单报表示例

简单报表 概述 简单表格报表&#xff1a;简单的表格报表。 应用场景 如下图所示&#xff0c;简单展示数据 示例说明 数据准备 在数据面板中添加数据集&#xff0c;可选择Json数据集和API服务数据集。Json数据集输入如下图所示&#xff1a; [{"到货日期":&qu…

工业智能网关在制造业数字化转型中的应用分享-天拓四方

随着工业4.0和物联网技术的飞速发展&#xff0c;工业智能网关已成为连接现场设备、实现数据采集与远程监控的关键节点。本文将以一个实际使用案例为蓝本&#xff0c;深入探讨工业智能网关的应用价值、技术特点以及实施效果&#xff0c;旨在为读者呈现一个清晰、专业且实操性强的…

vue项目打包问题

缓存导致打包后js文件404 修改vue.config.js打包输出文件名为动态&#xff0c;例如取当前时间戳。 在index.html文件添加meta标签设置不缓存。 更新完包&#xff0c;假如用户此刻正访问某一个页面时&#xff0c;访问的包还是原来的情况导致出现bug 解决VUE项目更新后需要客户手…

渲染引擎实践 - UnrealEngine引擎的 GLContext 创建过程

一:概述: 本文分析下 UnrealEngine 启动过程中创建多少个 OpenGL Context,以及每个 Context 的作用。 基于 UnrealEngine 4.25 环境。 二:临时Context 1. PreInit -> PreInitPreStartupScreen -> PreloadResolutionSettings, 用于检查图形窗口分辨率 2. PreInit -&…

Nmap——网络扫描的强大利器

一、引言 在网络安全和管理的领域中&#xff0c;了解网络的拓扑结构、设备状态以及开放的服务端口等信息至关重要。Nmap&#xff08;Network Mapper&#xff09;作为一款功能强大的网络扫描工具&#xff0c;为我们提供了深入探索网络的能力。本文将详细介绍 Nmap 的特点、功能…

三款新手剪辑软件分享,告别复杂的达芬奇剪辑软件

你们知道吗&#xff1f;一个视频能不能火&#xff0c;除了内容要够硬核&#xff0c;剪辑也是门大学问呢&#xff01;之前尝试过达芬奇剪辑&#xff0c;发现我不是很会用&#xff0c;然后最近我轮番上阵&#xff0c;试用了三款神器&#xff0c;来来来&#xff0c;让我给你们说说…

回归评价指标

这里写目录标题 1. 均方误差MSE2. 均方根误差RMSE3. 平均绝对误差MAE4. R^2^5. 调整后R^2^1. 均方误差MSE 回归数据和原始数据误差的平方和/原始数据个数平方的原因:不平方正负误差会抵消,对大误差更为敏感,在一些场景下更能凸显出模型预测的不准确性越接近于0,模型预测能力…

前端(三):Ajax

一、Ajax Asynchronous JavaScript And XML&#xff0c;简称Ajax&#xff0c;是异步的JavaScript和XML。 作用&#xff1a;数据交换&#xff0c;通过Ajax可以给服务器发送请求&#xff0c;并获取服务器响应的数据。异步交互&#xff1a;可以在不重新加载整个页面的情况下&…

雷达气象学(2)——雷达电磁波的衰减

文章目录 2.1 衰减的概念2.2 气体对电磁波的衰减2.3 云对电磁波的衰减2.4 雨对电磁波的衰减2.5 雪对电磁波的衰减2.5.1 干雪对电磁波的衰减2.5.2 湿雪对电磁波的衰减 2.6 冰雹对电磁波的衰减 2.1 衰减的概念 衰减是电磁波能量沿传播路径减弱的现象。造成衰减的原因是当电磁波投…

8.9套题

A. 猴猴吃苹果 题意&#xff1a;给定根节点k&#xff0c;求访问点的顺序&#xff0c;使得每次从上一个点到当前点的权值最大。访问过的点权值为0。权值一样时&#xff0c;输出最小编号 思路&#xff1a;由于是双向边&#xff0c;先求根节点到每一个节点的距离值。在第一轮中&…

WPF篇(3)- WrapPanel控件(瀑布流布局)+DockPanel控件(停靠布局)

WrapPanel控件&#xff08;瀑布流布局&#xff09; WrapPanel控件表示将其子控件从左到右的顺序排列&#xff0c;如果第一行显示不了&#xff0c;则自动换至第二行&#xff0c;继续显示剩余的子控件。我们来看看它的结构定义&#xff1a; public class WrapPanel : Panel {pub…

rocketMQ5.0事务消息实战

事务消息逻辑 首先我们来docker 部署rocketMQ与rocketMQDashBoard docker ps查看rocketMQ 容器名称 docker ps 进入容器内部 docker exec -it rmqnamesrv /bin/bash 创建事务消息 sh mqadmin updateTopic -c DefaultCluster -t TRANSACTIONTopic -n 127.0.0.1:9876 -a mes…

Python开源项目月排行 2024年7月

#2024年7月2024年8月2日1the-art-of-command-line一个全面而简洁的命令行使用指南。它旨在帮助工程师提高在命令行环境下的熟练程度和生产力。项目涵盖了从基础到高级的各种命令行技巧和知识&#xff0c;项目的内容涵盖了基础知识、日常使用、文件处理、系统调试等多个方面&…

图像自动化保存工具:Python脚本开发指南

引言 在数字化时代&#xff0c;图像已成为信息传递的重要媒介。无论是社交媒体、新闻网站还是电子商务平台&#xff0c;图像的自动化处理和保存都是提升用户体验和工作效率的关键。本文将深入探讨如何使用Python脚本实现从百度图片等搜索引擎批量下载并保存图像文件的高级应用…

第36集《大佛顶首楞严经》

请大家打开讲义第八十页&#xff0c;子三&#xff0c;明鼻识界即藏性。 蕅益大师讲到&#xff0c;我们修学大乘佛法&#xff0c;有一句话是很重要的。他说&#xff1a;“未开圆解&#xff0c;不应辄论修证。”说一个菩萨你没有真正地大彻大悟开圆顿解&#xff0c;你没有资格谈…

K8s问题案例分析

1.worker节点宕机&#xff0c;请说明一下pod的驱逐流程&#xff1a; k8s有一个节点控制器&#xff0c;节点控制器在一段时间内无法和kubelet通信&#xff0c;那么就会给节点打上unknown 状态&#xff0c;并自动创建NoExecute污点,避免调度器调度新的pod到该节点。同时已经在这…

2024年6月scratch图形化编程等级考试三级真题

202406 青少年软件编程等级考试Scratch三级真题 试卷总分数&#xff1a;100分 考试时长&#xff1a;60 分钟 第 1 题 运行程序后&#xff0c;角色的x坐标是&#xff1f;&#xff08; &#xff09; A&#xff1a;99 B&#xff1a;100 C&#xff1a;199 D&#xff1a;200 正…

Shell 脚本中的循环语句、函数与数组

文章目录 Shell 脚本中的循环语句、函数与数组1. for 循环1.1 for 循环语法结构1.1.1 列表循环1.1.2 不带列表循环1.1.3 类C风格的for循环 1.2 案例1.2.1 打印1-5这5个数字1.2.2 打印5次hello world1.2.3 打印abcde1.2.4 输出0-50之间的偶数 1.3 小技巧&#xff1a;花括号 {} 和…

力扣爆刷第171天之TOP200五连刷121-125(跳跃游戏、买卖股票、旋转链表)

力扣爆刷第171天之TOP200五连刷121-125&#xff08;跳跃游戏、买卖股票、旋转链表&#xff09; 文章目录 力扣爆刷第171天之TOP200五连刷121-125&#xff08;跳跃游戏、买卖股票、旋转链表&#xff09;一、55. 跳跃游戏二、123. 买卖股票的最佳时机 III三、排序奇升偶降链表四、…

【mysql 第四篇章】bin log 的作用是啥呢?

一、redo Log 介绍 redo log 是一种偏向物理性质的重做日志&#xff0c;因为他里面记录类似的这样的东西&#xff0c;“对那个数据也中的什么记录&#xff0c;做了个什么修改”。它是 InnoDB 存储引擎特有的东西。 二、bin Log 日志 bin log 叫做归档日志&#xff0c;它里面…