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 类并停止观察该图片,从而释放资源。

相关推荐
ZZZCY20038 分钟前
路由策略与路由控制实验
前端·网络
shawya_void17 分钟前
javaweb-day01-html和css初识
前端·css·html
khatung18 分钟前
React——useReducer
前端·javascript·vscode·react.js·前端框架·1024程序员节
思考的橙子20 分钟前
CSS之3D转换
前端·css·3d
木子七44 分钟前
vue3-setup中使用响应式
前端·vue
廖子默1 小时前
提供html2canvas+jsPDF将HTML页面以A4纸方式导出为PDF后,内容分页时存在截断的解决思路
前端·pdf·html
Moment1 小时前
毕业半年,终于拥有了两个近 500 star 的开源项目了 🤭🤭🤭
前端·后端·开源
光影少年1 小时前
react和vue图片懒加载及实现原理
前端·vue.js·react.js
AndyGoWei1 小时前
react react-router-dom history 实现原理,看这篇就够了
前端·javascript·react.js