找回密码
 立即注册
首页 业界区 业界 ResizeObserver和IntersectionObserver的详细讲解

ResizeObserver和IntersectionObserver的详细讲解

决任愧 2025-6-13 08:21:15
ResizeObserver 的介绍

ResizeObserver 用于异步观察元素的尺寸变化。
如:SVG 元素或文本节点的大小变化、调整浏览器窗口大小、动态改变某个元素的大小时
可以触发相应的回调处理逻辑。
当这些目标的大小变化时,ResizeObserver 将会触发一个回调函数
特别提醒:ResizeObserver 在初始观察元素时就会触发回调
Resize 读音:/ˌriːˈsaɪ z/
Observer 读音:/əbˈzɜː və(r)/
ResizeObserver的基本语法
  1. const target = document.getElementById('xx')
  2. ResizeObserver.observe(target,{box: "content-box"})
复制代码
target 表示需要观察的元素,必须填写
box属性:指定监听的盒模型类型,可选值。包括有下面的值
"content-box"(默认值):监听内容区域尺寸变化
"border-box":监听包含边框和内边距的尺寸变化
"device-pixel-content-box":监听设备像素相关的尺寸变化(适用于高精度场景)
ResizeObserver的基本使用

1,首先获取需要被观察的元素
2,创建实例对象,对象发生变化后需要处理的业务逻辑
  1. const ResizeObserver = new ResizeObserver((entriesArr)=>{
  2.     entriesArr.forEach(entry => {
  3.       console.log('变化元素尺寸需要处理的业务逻辑:', entry.contentRect);
  4.     });
  5.    })
复制代码
3,最后通过resizeObserver.observe(target) 进行进行观察
下面请看如何具体的使用
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.   <title>Document</title>
  7.   
  8. </head>
  9. <body>
  10.   我是一个元素
  11. </body>
  12. </html>
复制代码
1.png

ResizeObserver 在初始观察元素时就会触发回调?

是的,在初始观察元素时。
ResizeObserver 会立即执行一次回调,以提供元素的初始尺寸。
这样设计的好处是:我们可以立即获取到元素的尺寸。
ResizeObserver如何一次性监听多个目标
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.   <title>Document</title>
  7.   
  8. </head>
  9. <body>
  10.   
  11.     我是第1个元素
  12.     我是第2个元素
  13.     我是第3个元素
  14.   
  15.   <button id="btn">停止观察</button>
  16. </body>
  17. </html>
复制代码
2.png

停止观察特定的目标元素

有些时候我们不需要在观察某个特定的目标
此时,可以停止观察这个特定的目标,它对于性能优化有非常大的作用。
语法:resizeObserver.unobserve("停止观察的元素");
当我们缩放屏幕的时候,我们可以发现在控制台会有输出元素的宽高。
3.png

当我们点击停止观察后,控制台不会在有输出,因为我们停止观察这个元素了。
4.png
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.   <title>Document</title>
  7.   
  8. </head>
  9. <body>
  10.   我是一个元素
  11. </body>
  12. </html>  停止观察
复制代码
disconnect 停止观察所有目标元素

disconnect可以停止观察所有目标元素。
效果与unobserve相同
他们之间的区别是:disconnect 是停止所有的。
unobserve是停止特定的某个元素
  1. ...其他代码保持不变
  2. // 点击按钮后,停止观察所有目标元素
  3. const btn=document.getElementById('btn')
  4. btn.addEventListener('click',()=>{
  5.   resizeObserver.disconnect()
  6. })
复制代码
contentRect 的含义

细心的小伙伴发现了,我们在获取宽高的使用使用了 xxx.contentRect.width来获取。
这个contentRect 是啥东西?
其实:contentRect 是一个 DOMRectReadOnly 对象,包含以下只读属性
width:元素内容区域的宽度(不含 padding/border)
height:元素内容区域的高度
x/y:内容区域相对于根元素(或视口)的坐标
top/left/right/bottom:内容区域的边界位置
低版本浏览器如何处理

如果担心ResizeObserver的兼容性可使用resize-observer-polyfill这个插件
首先: npm install resize-observer-polyfill --save-dev
使用如下
  1. import ResizeObserver from 'resize-observer-polyfill';
  2. const plugInObserver = new ResizeObserver((entriesArr, observer) => {
  3.     for (const entry of entriesArr) {
  4.       const { contentRect } = entry; // 这里使用了结构的哈
  5.       console.log('Element resized:', contentRect);
  6.     }
  7. });
  8. // 获取需要监听的DOM元素
  9. const element = document.getElementById('yourElement');
  10. plugInObserver.observe(element);
复制代码
用节流提升性能

如果触发的很频繁的话,我们可以使用节流的方式来降低触发频率
  1. function throttle(func, delay) {
  2.     let begin = 0;
  3.     return function () {
  4.         var cur = new Date().getTime();
  5.         if (cur - begin > delay) {
  6.             func.apply(this, arguments)
  7.             begin = cur
  8.         }
  9.     }
  10. }
  11. const myObserver = new ResizeObserver(throttle(entriesArr=> {
  12.   entriesArr.forEach(entry => {
  13.     console.log('大小位置 contentRect', entry.contentRect)
  14.     console.log('监听的DOM target', entry.target)
  15.   })
  16. }), 200)
复制代码
IntersectionObserver的简单介绍

IntersectionObserver API是用来观察元素是否可见,通常被我们叫做:“交叉观察器”。
和 ResizeObserver 一样,在初始观察元素时就会触发回调函数
Intersection 读音:/ɪn tə ˈse k ʃn/ 十字路口,交叉,交点
ResizeObserver 的观察配置

ResizeObserver 有3个非常重要的配置项。
  1. let options = {
  2.   root: null, // 观察目标的上层元素。如:父级元素。爷爷元素。默认为视口。
  3.   rootMargin: '0px', // 视口向外扩展的距离
  4.   threshold: 0.1  // 观察对象与视口交叉的范围,取值[0,1]。0表示碰上。1表示要完全看见。
  5.   // 0.1表示:目标元素与视口可见比例达到 10% 时触发回调
  6. };
  7. let watchObject = new IntersectionObserver(()=>{
  8.   console.log('触发时执行的回调函数')
  9. }, options);
复制代码
rootMargin视口向外扩展的距离

5.png

IntersectionObserver的使用场景

1,懒加载图片
2,无限滚动加载
3,展示加载动画
下面我们就使用IntersectionObserver实现懒加载。
让大伙更加熟悉这个api的实验
停止观察

disconnect() 停止监视所有目标元素的可见性变化并销毁观察者。
unobserve(targetElement) 停止观察指定的目标元素
静态布局

静态页面,先写一下图片的布局。
图片的src设置为空,真实的地址在自定义属性data-rsc中。
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.   <title>Document</title>
  7.    
  8. </head>
  9. <body>
  10.   
  11.    
  12.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  13.    
  14.    
  15.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  16.    
  17.    
  18.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  19.    
  20.    
  21.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  22.    
  23.    
  24.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  25.    
  26.    
  27.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  28.    
  29.    
  30.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  31.    
  32.    
  33.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  34.    
  35.    
  36.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  37.    
  38.    
  39.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  40.    
  41.    
  42.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  43.    
  44.    
  45.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  46.    
  47.    
  48.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  49.    
  50.    
  51.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  52.    
  53.    
  54.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  55.    
  56.    
  57.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  58.    
  59.    
  60.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  61.    
  62.    
  63.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  64.    
  65.    
  66.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  67.    
  68.    
  69.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  70.    
  71.   
  72. </body>
  73. </html>
复制代码
26.png

使用IntersectionObserver实现懒加载
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.   <title>Document</title>
  7.    
  8. </head>
  9. <body>
  10.   
  11.    
  12.       <img src="" data-src="https://plus.unsplash.com/premium_photo-1666278379770-440439b08656?w=600&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8YW5pbWFsc3xlbnwwfHwwfHx8MA%3D%3D"/>
  13.    
  14.    
  15.       <img src="" data-src="https://images.unsplash.com/photo-1529778873920-4da4926a72c2?w=600&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mnx8YW5pbWFsc3xlbnwwfHwwfHx8MA%3D%3D"/>
  16.    
  17.    
  18.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  19.    
  20.    
  21.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  22.    
  23.    
  24.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  25.    
  26.    
  27.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  28.    
  29.    
  30.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  31.    
  32.    
  33.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  34.    
  35.    
  36.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  37.    
  38.    
  39.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  40.    
  41.    
  42.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  43.    
  44.    
  45.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  46.    
  47.    
  48.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  49.    
  50.    
  51.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  52.    
  53.    
  54.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  55.    
  56.    
  57.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  58.    
  59.    
  60.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  61.    
  62.    
  63.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  64.    
  65.    
  66.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  67.    
  68.    
  69.       <img src="" data-src="https://images.pexels.com/photos/106399/pexels-photo-106399.jpeg"/>
  70.    
  71.   
  72. </body>
  73. </html>
复制代码
47.png

intersectionRatio,isIntersecting,target,time属性的详细讲解

intersectionRatio:number
表示目标元素与根元素的交叉区域的比例,即交叉区域面积与目标元素总面积的比值。
当目标元素完全可见时,值为1;完全不可见时,值为0。返回的是一个类型的值
如果元素部分可见,则是一个介于0和1之间的值。
isIntersecting:boolean
表示目标元素是否与根元素相交(交叉)。如果相交(即使交叉区域为零)则为true;否则为false。
true: 当元素开始进入或仍在交叉区域
false: 当元素完全离开交叉区域
target:Element
表示:被观察的目标元素。
用途: 在多个观察目标中识别当前触发的元素
time: number
描述: 交叉状态变化的时间戳(从页面加载开始计算,单位:毫秒)
用途:1,计算交叉事件的精确时间。2,性能分析(如计算元素进入视口的耗时)
48.png

尾声

今天周五啦,开心
                                                                                                                               
49.jpeg
                                                微信                                                                                                本文版权归作者所有,欢迎转载,未经作者同意须保留此段声明,在文章页面明显位置给出原文连接
                        如果文中有什么错误,欢迎指出。以免更多的人被误导。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
6.jpeg
7.jpeg
8.jpeg
9.jpeg
10.jpeg
11.jpeg
12.jpeg
13.jpeg
14.jpeg
15.jpeg
16.jpeg
17.jpeg
18.jpeg
19.jpeg
20.jpeg
21.jpeg
22.jpeg
23.jpeg
24.jpeg
25.jpeg
27.webp
28.webp
29.jpeg
30.jpeg
31.jpeg
32.jpeg
33.jpeg
34.jpeg
35.jpeg
36.jpeg
37.jpeg
38.jpeg
39.jpeg
40.jpeg
41.jpeg
42.jpeg
43.jpeg
44.jpeg
45.jpeg
46.jpeg
您需要登录后才可以回帖 登录 | 立即注册