js属性-IntersectionObserver

js属性-IntersectionObserver

接下来我们主要认识一下原生JavaScriptAPI-IntersectionObserver这个API

1、认识IntersectionObserver

介绍:IntersectionObserver 是一种原生JavaScript API,用于异步监测元素与其祖先元素(或视口)交叉状态的变化。

也就是说,帮助我们监听某个元素进入或离开视口时的操作

应用场景:懒加载图片、触发动画效果、无限滚动等

优势:与传统的滚动监听方法相比,不需要不断监听滚动事件,而是由浏览器在合适的时候自动触发,减少了性能开销也更高效。

2、基本使用

IntersectionObserver通过一个观察器来监听元素的交叉状态变化。观察器会接收两个主要的参数:

回调函数(callback):当监听的元素的交叉状态发生变化时,会调用此回调函数。

配置对象(options):配置观察器行为的选项,包括根元素、阈值

我们先来看一个代码基本案例,再进行分析

先来写一下我们的结构

javascript 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>js-IntersectionObserver</title>
    <style>
    .tablie {
        width: 100%;
        height: 400px;
        border: 1px solid #ccc;
        transition: all 1s;
    }
    </style>
</head>
<body style="height:100vh;padding: 20px 100px;">
    <div style="height: 1600px;width:100%;">
        <div class="tablie" id="box">我是测试</div>
        <div class="tablie"></div>
        <div class="tablie"></div>
        <div class="tablie"></div>
        <div class="tablie"></div>
        <div class="tablie"></div>
        <div class="tablie"></div>
        <div class="tablie"></div>
    </div>
</body>
</html>

添加一下我们的script ,然后我们看看

javascript 复制代码
const observer = new IntersectionObserver((entries, observer) => {
   entries.forEach(entry => {
          if (entry.isIntersecting) {
              console.log('元素进入视口', 111);
              console.log(entry.target.id);
              entry.target.style.backgroundColor = 'lightgreen';
          } else {
              console.log('元素离开视口', 222);
              entry.target.style.backgroundColor = 'lightblue';
          }
      });
  }, {
      root: null, // 观察视口,null 代表整个浏览器窗口
      rootMargin: '0px', // 视口边缘的额外间距
      threshold: 0.5 // 触发回调的交叉比例(0到1之间)
  });
  const box = document.getElementById('box'); // 获取要观察的元素
  observer.observe(box); // 开始观察元素

思路分析

上面的代码的整个过程如下:

先来看看上面整个部分是哪些东西,简单总结一个,其实非常简单(回调函数+配置对象)

javascript 复制代码
(1) 创建一个IntersectionObserver 实例,并提供一个回调函数来处理元素交叉状态变化。
(2) 配置root等配置
(3) 使用observe() 方法将目标元素添加到观察器中,这里我们是为了观察目标元素,
    开始监控 target-element 元素
    当其与视口的交叉状态发生变化时,我们就可以调用回调函数。

3、参数

回调函数(callback)

回调函数callback接收两个参数entries和observer

javascript 复制代码
new IntersectionObserver((entries, observer) => {})

entries包含所有被观察元素的 IntersectionObserverEntry 对象数组,所以上面的示例之中我们为什么用forEach的原因也清晰了。

forEach中的每个对象都代表一个被观察的元素,有该元素交叉状态信息( isIntersecting(是否与视口交叉)、intersectionRatio(交叉比例)、boundingClientRect(元素的矩形框))等一些属性。

配置对象(options)

先来看看我们配置对象里面的一些属性
root :观察的根元素,利用这个属性我们可以设置视口元素,默认为 null,表示浏览器窗口。当我们监控一个特定的父容器的视口,可以设置为该容器。

rootMargin:根元素的边缘间距

javascript 复制代码
rootMargin: '10px 0px' : 视口上下方向上10px的范围

threshold :触发回调的交叉比例,设置交叉比例的阈值(数字或数字数组-- 0 到 1 ),代表目标元素与根元素交叉的比例

threshold :0.5 当元素至少有 50% 可见时才触发回调

0.5 :当目标元素有 50% 可见时就触发回调。

0, 0.5, 1 :当目标元素的可见比例为 0%、50%、100% 时都会触发回调

4、优化和剖析

停止观察目标元素

监听完元素以后可以移除元素,优化性能

javascript 复制代码
observer.unobserve(target);

 entries.forEach(entry => {
    if (entry.isIntersecting) {
        const loadElement = entry.target;
        console.log('元素进入视口', 111);
        console.log(loadElement.id);
        loadElement.style.backgroundColor = 'lightgreen';
        observer.unobserve(loadElement);         // 加载完成后停止观察

    } else {
        console.log('元素离开视口', 222);
        entry.target.style.backgroundColor = 'lightblue';
    }
});

关闭所有元素

当我们需要完全停止所有的观察,可以使用 disconnect() 方法。

javascript 复制代码
observer.disconnect();

5、实战应用

图片懒加载

接下来我们尝试一个常见的使用场景,懒加载图片,当图片进入视口时,才加载图片内容

注:**data-src**图片懒加载具体属性可以查看图片篇

javascript 复制代码
<img data-src="image1.jpg"class="lazy"alt="Image 1">
<img data-src="image2.jpg"class="lazy"alt="Image 2">

const lazyImages = document.querySelectorAll('.lazy');

// 创建 IntersectionObserver 实例
const observer = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    // 当图片进入视口时,加载图片
    if (entry.isIntersecting) {
      const lazyImage = entry.target;
      lazyImage.src = lazyImage.dataset.src;  // 使用数据属性加载图片
      lazyImage.classList.remove('lazy');    // 移除懒加载类
      observer.unobserve(lazyImage);         // 加载完成后停止观察该图片
    }
  });
}, { threshold: 0.1 });

// 观察每个懒加载图片
lazyImages.forEach(image => {
  observer.observe(image);
});

分析:

懒加载图片之中,带有 data-src 属性的懒加载图片,图片的真实 src 地址保存在 data-src 中,初始 src 为空或为占位符。

利用 IntersectionObserver,当图片进入视口时,回调函数会被调用,图片的 src 属性会被设置为 data-src 的值,达到懒加载图片。

当图片加载后,移除 lazy 类并停止观察该图片,从而释放资源。

相关推荐
卸任1 小时前
Vibe coding工具使用心得
前端·ai编程
brien92 小时前
为什么模型标称 1M,Google Antigravity 聊到 256K 却突然失忆?我们给它做了个原生行内监控圆环
前端
修炼的dance2 小时前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M2 小时前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写2 小时前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李2 小时前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易2 小时前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
清晨Coding2 小时前
删了 Cookie 还能自动登录?Google系网站登录态自动恢复的原理分析
javascript
风骏时光牛马3 小时前
前沿视界
前端
kyriewen3 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员