当前位置: 首页 > news >正文

面试之《IntersectionObserver的使用》

IntersectionObserver 是一个 Web API,用于异步观察目标元素与其祖先元素或顶级文档视口(viewport)交叉状态的变化。这在很多场景下非常有用,比如懒加载图片、实现无限滚动加载更多内容等。下面详细介绍它的使用方法。

基本原理

IntersectionObserver 允许你注册一个回调函数,当目标元素进入或离开指定的根元素(通常是视口)的可见区域时,这个回调函数就会被调用。

构造函数

IntersectionObserver 的构造函数接受两个参数:

const observer = new IntersectionObserver(callback, options);
  • callback:当目标元素的可见性发生变化时执行的回调函数。该回调函数接收两个参数:
    • entries:一个包含所有被观察元素的 IntersectionObserverEntry 对象的数组,每个对象描述了一个被观察元素的交叉状态变化。
    • observer:当前的 IntersectionObserver 实例。
  • options:一个可选的配置对象,包含以下属性:
    • root:指定根元素,即用于检查目标元素可见性的元素。默认为浏览器视口,如果指定了该属性,则必须是目标元素的祖先元素。
    • rootMargin:根元素的外边距,用于扩展或缩小根元素的边界框。可以使用类似于 CSS margin 属性的值,例如 '10px 20px 30px 40px'
    • threshold:一个单值或数组,表示目标元素与根元素交叉区域占目标元素总面积的比例。可以是一个介于 0 和 1 之间的数字,或者是一个包含多个这样数字的数组。例如,0 表示目标元素的任何部分进入根元素的可见区域时触发回调,1 表示目标元素完全进入根元素的可见区域时触发回调。

使用步骤

1. HTML 结构

首先,创建一个简单的 HTML 结构,包含一些需要观察的元素。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IntersectionObserver Example</title>
    <style>
        .box {
            width: 200px;
            height: 200px;
            background-color: lightblue;
            margin: 20px;
        }
    </style>
</head>

<body>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <script src="script.js"></script>
</body>

</html>
2. JavaScript 代码

script.js 文件中,使用 IntersectionObserver 来观察这些元素。

// 获取所有需要观察的元素
const boxes = document.querySelectorAll('.box');

// 定义回调函数
const callback = (entries, observer) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            // 当元素进入视口时,添加一个类名来改变样式
            entry.target.classList.add('active');
            // 停止观察该元素
            observer.unobserve(entry.target);
        }
    });
};

// 创建 IntersectionObserver 实例
const observer = new IntersectionObserver(callback, {
    root: null, // 使用浏览器视口作为根元素
    rootMargin: '0px', // 根元素的外边距
    threshold: 0.5 // 当目标元素的 50% 进入视口时触发回调
});

// 开始观察每个元素
boxes.forEach(box => {
    observer.observe(box);
});

示例解释

  • 首先,使用 document.querySelectorAll 方法获取所有需要观察的 .box 元素。
  • 然后,定义了一个回调函数 callback,当目标元素的可见性发生变化时会执行该函数。在回调函数中,遍历 entries 数组,检查每个元素是否进入视口(entry.isIntersecting),如果进入视口,则添加一个类名 active 来改变元素的样式,并使用 observer.unobserve 方法停止观察该元素。
  • 接着,创建了一个 IntersectionObserver 实例,指定了回调函数和配置选项。
  • 最后,使用 observer.observe 方法开始观察每个元素。

其他用途

  • 懒加载图片:可以在图片进入视口时再加载图片,提高页面性能。
<img class="lazy" data-src="image.jpg" alt="Lazy loaded image">
const lazyImages = document.querySelectorAll('.lazy');
const lazyCallback = (entries, observer) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const img = entry.target;
            img.src = img.dataset.src;
            img.classList.remove('lazy');
            observer.unobserve(img);
        }
    });
};
const lazyObserver = new IntersectionObserver(lazyCallback);
lazyImages.forEach(img => {
    lazyObserver.observe(img);
});
  • 无限滚动加载更多内容:当页面滚动到底部时,加载更多的内容。
const loadMoreCallback = (entries, observer) => {
    const entry = entries[0];
    if (entry.isIntersecting) {
        // 加载更多内容的逻辑
        console.log('Load more content');
    }
};
const loadMoreObserver = new IntersectionObserver(loadMoreCallback);
const loadMoreElement = document.querySelector('.load-more');
loadMoreObserver.observe(loadMoreElement);

通过使用 IntersectionObserver,可以更高效地处理元素的可见性变化,提高页面的性能和用户体验。

相关文章:

  • AI 大模型统一集成|让 AI 聊天更丝滑:WebSocket 实现流式对话!
  • 数据批处理(队列方式)
  • 高并发场景下如何实现消息精准一次消费?实战Java幂等性设计
  • 如何阅读webpack-bundle-analyzer分析生成的图
  • MySQL regexp 命令
  • C++基础(VScode环境安装)
  • MyBatis 的配置对象 Configuration 作用详解
  • 【QT】QScrollBar设置样式:圆角、隐藏箭头、上边距等
  • Qt配置OpenGL相机踩的坑
  • 蓝桥杯 C++ b组 统计子矩阵双指针+一维前缀和
  • 【2025深夜随笔】简单认识一下Android Studio
  • Redis 缓存穿透、缓存击穿与缓存雪崩详解:问题、解决方案与最佳实践
  • C语言一维数组
  • SD模型进阶学习全攻略(三)
  • 深入理解Mesa:Linux图形渲染背后的开源力量
  • OSPF总结
  • 正则表达式快速入门
  • MyBatis 中SQL 映射文件是如何与 Mapper 接口关联起来的? MyBatis 如何知道应该调用哪个 SQL 语句?
  • 高校数字素养通识教育解决方案
  • 饮食调治痉挛性斜颈,开启健康生活
  • 上海第三家“胖永辉”在浦东开业,设立了外贸产品专区
  • 13家券商一季报出炉:超七成业绩预喜,财通、湘财、第一创业下滑
  • 当智驾成标配,车企暗战升级|2025上海车展
  • 持续更新丨伊朗港口爆炸事件已致406人受伤
  • 华夏银行青岛分行另类处置不良债权,德州近百亩土地被神奇操作抵押贷款
  • 吃饭睡觉打国米,如今的米兰把意大利杯当成宝