首页 > 其他分享 >getBoundingClientRect 和 IntersectionObserver 的区别和用法

getBoundingClientRect 和 IntersectionObserver 的区别和用法

时间:2024-07-26 14:50:57浏览次数:13  
标签:observer getBoundingClientRect 元素 用法 视口 entry IntersectionObserver

目录

getBoundingClientRect

getBoundingClientRect 是一个 DOM API 方法,用于获取指定元素相对于视口的位置和尺寸信息。它返回一个 DOMRect 对象,包含了元素的左上角和右下角相对于视口的坐标。
“图片懒加载”,这个词语想必大家再熟悉不过了。传统的实现方法是,监听 scroll 事件,获取 img 元素相对于视口的顶点位置 el.getBoundingClientRect().top,只要这个值小于浏览器的高度 window.innerHeight 就说明进入可视区域,当图片进入可视区域时再去加载图片资源。

这种方法的缺点是,由于 scroll 事件密集发生,计算量很大,容易造成性能问题。

const element = document.getElementById("myElement");
const rect = element.getBoundingClientRect();

console.log(rect.top); // 元素顶部相对于视口的距离
console.log(rect.left); // 元素左侧相对于视口的距离
console.log(rect.width); // 元素的宽度
console.log(rect.height); // 元素的高度

IntersectionObserver

IntersectionObserver 是一个用于监听元素与视口交叉状态的 API(交叉观察器)。异步地观察一个或多个元素,当它们进入或离开视口时触发回调函数。

使用 IntersectionObserver,可以实现一些常见的交互效果,例如懒加载、无限滚动、可视化统计、网页广告的曝光量统计等。下面是一个简单的示例:

创建了一个 IntersectionObserver 实例,并通过 observe 方法观察了一个元素。当该元素进入或离开视口时,回调函数会被触发,并根据 isIntersecting 属性判断元素的可见状态。

// 指定根元素root、根元素的外边距rootMargin、执行callback的交叉比例的阀值threshold
const options = {
  root: null, // 观察器的根元素,必须是目标元素的父级元素; 默认:文档视口
  rootMargin: "0px", // 根元素的边界偏移量,类似于 CSS 中的 margin 属性。默认值是"0px 0px 0px 0px"
  threshold: 0.5, // 交叉比例阈值,当元素可见比例超过该阈值时触发回调函数
};

const observer = new IntersectionObserver((entries, observer) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      console.log("Element is visible"); // 元素进入视口
    } else {
      console.log("Element is hidden"); // 元素离开视口
    }
  });
}, options);

const element = document.getElementById("myElement");
observer.observe(element);

定义观察到目标元素与根元素交叉区域变化时的回调函数 callback(entries, observer)。entries 数组中,每个成员都是一个 IntersectionObserverEntry 对象,如果同时有两个被观察的对象的可见性发生变化,entries 数组就会有两个成员。一般会触发两次 callback。一次是目标元素刚刚进入视口(开始可见),另一次是完全离开视口(开始不可见)。

let callback = (entries, observer) => {
  entries.forEach((entry) => {
    consloe.log(entry); //包含目标元素的信息的对象
    // entry.time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒
    // entry.target:被观察的目标元素,是一个 DOM 节点对象
    // entry.rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
    // entry.boundingClientRect:目标元素的矩形区域的信息
    // entry.intersectionRect:目标元素与视口(或根元素)的交叉区域的信息
    // entry.intersectionRatio:根和目标元素的交叉区域的比例值,即intersectionRect占boundingClientRect的比例,0 为完全不可见,1 为完全可见
    // entry.isIntersecting:true表示从不可视状态变为可视状态。false表示从可视状态到不可视状态:false
  });
};

// observer.observe(targetNode);   指定目标元素 targetNode1、targetNode2,开始观察。
//observe的参数是一个 DOM 节点对象。如果要观察多个节点,就要多次调用这个方法。
observer.observe(targetNode1);
observer.observe(targetNode2); //开始观察目标元素。
// observer.disconnect(); //关闭观察器。
// observer.takeRecords(); //返回所有观察目标对象数组。
// observer.unobserve(targetNode1); //停止观察特定目标元素。

标签:observer,getBoundingClientRect,元素,用法,视口,entry,IntersectionObserver
From: https://www.cnblogs.com/echoyya/p/17941409

相关文章

  • Arrays.sort()与Collections.sort()的用法以及区别
    目录Arrays.sort()与Collections.sort()的区别对象数组的排序方式Arrays.sort()的方法1.Arrays.sort(int[]a)2.Arrays.sort(int[]a,intfromIndex,inttoIndex)3.Arrays.sort(Integer[]a,Comparatorcmp)Collections.sort()的方法1.sort(Listlist)2.sort(Listlist......
  • 【Android】数据存储方案——文件存储、SharedPreferences、SQLite数据库用法总结
    文章目录文件存储存储到文件读取文件SharedPreferences存储存储获取SharedPreferences对象Context类的getSharedPreferences()方法Activity类的getPreferences()方法PreferenceManager类中的getDefaultSharedPreferences()方法示例读取记住密码的功能SQLite......
  • C语言分支语句之if的一些用法
    目录引言C语言结构1.if语句1.1if1.2else2.分支中包含多条语句3.多重选择elseif4.嵌套if5.悬空else/else与if配对问题引言C语言作为一种非常常用的编程语言,具有灵活强大的循环和分支结构。循环结构允许我们重复执行一段代码,而分支结构则允许我们根据条......
  • 关于Streamlit中button的扩展用法
    最近团队在制作一个车辆管理系统,本人刚好负责streamlit的页面可视化。这篇Blog就不详细赘述系统的各项功能了,今天主要是想写点东西,加深一下知识的理解和消化,各位看官看个开心~(手动分界线 /doge)--------------------------------------------------------------------------......
  • SQL中的declare用法
    SQL中的declare用法平时写SQL查询、存储过程都是凭着感觉来,没有探究过SQL的具体语法,一直都是按c#那一套往SQL上模仿,前几天项目中碰到一个问题引起了我对declare定义变量的作用域的兴趣。大家都知道c#中的局部变量,在if中如果我们定义一个变量的话他的作用到if结束为止,if外是不......
  • Rust 中 *、&、mut、&mut、ref、ref mut 的用法和区别
    Rust中*、&、mut、&mut、ref、refmut的用法和区别在Rust中,*、ref、mut、&和refmut是用于处理引用、解引用和可变性的关键字和操作符,它们在不同的上下文中有不同的用法。一、*解引用*属于操作符1.作用用于解引用指针或引用,以访问其指向的值。通过解引用,可以从指......
  • 指针的用法
    大家好,这次是用法系列第二期,给大家介绍指针的作用。一.用于变量我举个例子#include<iostream>usingnamespacestd;intmain(){ intx=6,y=5;//创建变量x,y int*p=&x;//创建指针p并指向x cout<<*p<<endl;//输出指针p *p=y;//指针指向y cout<<*p;//输出指针p......
  • Vue中deep的用法
    deep:true 的用法在Vue中,watch用来监听数据的变化,并执行相应的回调函数。当监听的对象是一个复杂的数据结构(如对象或数组)时,默认情况下Vue的watch只会监听顶层属性的变化,而不会监听对象内部属性的变化。例子假设您有如下数据结构:data(){return{user:{......
  • UVM-config_db机制和用法
    1.用途        config_db机制用于在UVM验证平台间传递参数,通常成对出现,其中set相当于寄信,get相当于收信。UVM提供的config_db机制可在组件实例化前就设定好配置信息,这样就可在tb的initial块中就进行设定了。真正将这些配置信息落实在各component,是在testbench运行过程......
  • C语言 ——— 函数指针数组的讲解及其用法
    目录前言函数指针数组的定义函数指针数组的使用前言数组是存放一组相同类型数据的存储空间关于指针数组的知识请见:C语言———指针数组&指针数组模拟二维整型数组-CSDN博客那么要将多个函数的地址存储到数组中,这个数组该如何定义呢?函数指针数组的定义把多个函数......