MutationObserver与IntersectionObserver的区别

今天主要是分享一下MutationObserver和IntersectionObserver的区别,希望对大家有帮助!

  1. MutationObserver IntersectionObserver 的区别

    • MutationObserver

      • 作用:用于监听 DOM 树的变动,包括:元素的属性、子元素列表或节点文本的变化。
      • 适用场景:可以用来检测 DOM 的结构和内容变化,比如元素被插入或删除、属性被更改等。
      • 性能:由于 MutationObserver 监听的是整个 DOM 树的变化,频繁的 DOM 操作会导致性能问题,因此适用于较少变化的场景。
    • IntersectionObserver

      • 作用:用于监听目标元素与其祖先元素(或 viewport)之间的交叉状态,即是否进入或离开视口。
      • 适用场景:适合用于检测元素是否在视口中,例如:实现图片懒加载、无限滚动或曝光监测。
      • 性能:由于它的监听目标是元素的可见性,相较于 MutationObserver,更适合频繁变化的场景。
    特性MutationObserverIntersectionObserver
    监听对象DOM 节点的结构、属性或文本变化目标元素与视口或指定元素的交叉状态
    常见使用场景检测 DOM 变化(插入、删除、修改)图片懒加载、曝光监测、滚动加载等
    性能频繁变化可能影响性能更适合高频率变化的监听
  2. 应用场景

    • IntersectionObserver

      在之前我分享的Vue3如何优雅地加载图片的时候,其实是使用过 IntersectionObserver 的。会使用它检测 DOM(img) 是否可见,以此来判断是否需要加载对应的图片:

      // 懒加载图片的回调函数,包含淡入效果和错误处理
      function lazyLoadImages(entries, observer) {
          entries.forEach(entry => {
              // 检查图片是否进入视口
              if (entry.isIntersecting) {
                  const img = entry.target;
                  img.src = img.dataset.src; // 将 src 替换为 src 开始加载图片
                  
                  // 图片加载成功后,添加 'loaded' 类触发淡入效果
                  img.onload = () => img.classList.add('loaded'); 
                  
                  // 图片加载失败时,显示默认占位图
                  img.onerror = () => img.src = 'placeholder.jpg'; 
                  
                  observer.unobserve(img); // 停止观察该图片
              }
          });
      }
      
      // 创建 IntersectionObserver 实例,用于懒加载
      const imageObserver = new IntersectionObserver(lazyLoadImages, { threshold: 0.1 });
      
      // 选取所有带有 src 属性的图片并开始观察
      document.querySelectorAll('img[src]').forEach(img => {
          imageObserver.observe(img);
      });
      

      除此之外,IntersectionObserver性能检测 中也有应用场景。

      // 处理元素可见性变化的回调函数
      function handleIntersection(entries, observer) {
          entries.forEach(entry => {
              // 检查元素是否进入视口
              if (entry.isIntersecting) {
                  console.log('元素已进入视口:', entry.target);
                  
                  // 调用自定义追踪事件函数,记录元素可见性
                  trackEvent('element_visible', { elementId: entry.target.id });
                  
                  // 可选:停止观察该元素(仅触发一次)
                  observer.unobserve(entry.target);
              }
          });
      }
      
      // 创建 IntersectionObserver 实例
      const observer = new IntersectionObserver(handleIntersection, {
          root: null,      // 使用视口作为容器
          threshold: 0.5   // 当元素 50% 可见时触发回调
      });
      
      // 选择需要观察的目标元素
      const targetElement = document.getElementById('target');
      observer.observe(targetElement);
      
      // 示例追踪事件函数
      function trackEvent(eventType, details) {
          console.log(`记录事件: ${eventType}`, details);
          // 在这里将追踪数据发送到服务器或分析服务
      }
      
    • MutationObserver

      MutationObserver 主要 监听 DOM 的动态变化(添加、删除 等)。在 SPA 应用中,动态加载的场景下会非常有用。

      比如,我们做一个评论提交的功能,当用户提交一条新评论时,我们希望检测到 DOM 变化并触发相关操作

      <div id="comments-section">
        <p>评论列表:</p>
        <div id="comments">
          <p>用户1: 很棒的文章!</p>
        </div>
      </div>
      
      <button onclick="addComment()">添加评论</button>
      
      <script>
        // 模拟添加评论
        function addComment() {
          const comment = document.createElement("p");
          comment.textContent = `用户${Date.now()}: 新的评论内容`;
          document.getElementById("comments").appendChild(comment);
        }
      
        // MutationObserver 实例
        const commentsSection = document.getElementById("comments");
        const observer = new MutationObserver((mutationsList) => {
          mutationsList.forEach((mutation) => {
            if (mutation.type === 'childList') {
                  // 调用自定义追踪事件函数,记录元素可见性
                  trackEvent('element_update', { elementId: target.target.id });
            }
          });
        });
      
        // 观察评论区的子节点变化
        observer.observe(commentsSection, {
          childList: true, // 监听子节点变化
        });
      </script>
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值