IntersectionObserverAPI实例

IntersectionObserver API

以下场景可以使用到IntersectionObserverAPI

  • 图片懒加载——当图片咕哝到可见时才进行加载
  • 内容无限滚动——也就是用户滚动到接近内容底部时直接加载更多,而无需用户操作翻页,给用户一种网页可以无限滚动的错觉
  • 检测广告的曝光情况——为了计算广告收益,需要知道广告元素的曝光情况
  • 在用户看见某个区域时执行任务或播放动画

API

IntersectionObserver是浏览器原声提供的构造函数,接受两个参数:callback是可见性变化时的回调函数,option是配置对象(改参数可选)
构造函数的返回值是一个观察器实例。实例的observe方法可以指定观察哪个DOM节点,如果需要观察多个DOM节点可以多次添加observe方法

//创建实例
const observer = new IntersectionObserver(callback,option);

//开始观察element1
observer.observe(element1)

//开始观察element2
observer.observe(element2)

//停止观察
observer.unobserve(element)

//关闭观察器
observer.disconnect();

callback参数

  • Observer第一次监听目标元素的时候执行
  • 每当目标元素与设备视窗或者其他指定元素发生交集的时候执行

callback函数的参数(entries)是一个数组,每个成员都是一个IntersectionObserverEntry对象。举例来说如果同时有两个被观察的对象的可见性发生变化,entries数组就会有两个成员。
每个IntersectionObserverEntry对象属性含义如下:

  • boundingClientRect:目标元素的矩形区域的信息
  • intersectionRatio:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0
  • intersectionRect:目标元素与视口(或根元素)的交叉区域的信息
  • rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
  • isIntersecting:目标元素是否与视口(或根元素)交叉
  • target:被观察的目标元素,是一个 DOM 节点对象
  • time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒

Option对象

IntersectionObserver构造函数的第二个参数是一个配置对象。它可以设置以下属性。

  • root:指定根元素,用于检查目标的可见性。必须是目标元素的父级元素。如果未指定或者为null,则默认为浏览器视窗。
  • rootMargin:根元素的外边距,类似于 CSS 中的margin属性。
  • threshold:目标元素与根元素的交叉比例,可以是单一的 number 也可以是 number 数组,比如,[0, 0.25, 0.5, 0.75, 1]就表示当目标元素 0%、25%、50%、75%、100% 可见时,会触发回调函数。

注意点

  • IntersectionObserverAPI是异步的,不随着目标元素的滚动同步触发
  • 注册的回调函数将会在主线程中被执行,所以该函数执行速度要尽可能的快。如果有些耗时的操作需要执行,建议使用Window.requestIdleCallback()方法

实例:无限滚动

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>IntersectionObserver</title>
</head>
<body style="font-size: 24px;text-align: center">
<div id="container"></div>
<div id="loadMore">加载中...</div>
</body>
<script>
  const container = document.querySelector('#container');
  const loadMore = document.querySelector('#loadMore');
  let index = 0;
 
  const loadItems = (count) => {
    [...Array(count).keys()].forEach((key) => {
      const p = document.createElement('P');
      console.log(key,index);
      p.innerHTML = `${key + index}`;
      container.appendChild(p)
    })
    index += count;
  }
 
  const observer = new IntersectionObserver((entries) => {
    entries.forEach(({ isIntersecting }) => {
      if (isIntersecting) {
        loadItems(20);
      }
    })
  });
 
  observer.observe(loadMore)
</script>
</html>

实例二:图片懒加载

图片懒加载会将img的src先剔除,当与适口产生交集的时候会动态添加src

<!DOCTYPE html>
<html>
<head>
  <title>图片懒加载示例</title>
  <style>
    #image-container {
      /* height: 600px; 用于产生滚动条 */
      overflow-y: scroll;
      display: flex;
      flex-direction: column;
      align-items: center;
    }
    img {
      height: 200px;
      width: 200px;
      margin-bottom: 20px;
      background-color: lightgray;


    }
  </style>
</head>
<body>
  <div id="image-container">
    <img class="lazy" data-src="./exam_banner3.png" alt="image1">
    <img class="lazy" data-src="./exam_banner4.png" alt="image2">
    <img class="lazy" data-src="./exam_banner5.png" alt="image3">
    <img class="lazy" data-src="./exam_banner6.png" alt="image3">
    <img class="lazy" data-src="./exam_banner5.png" alt="image3">
    <img class="lazy" data-src="./exam_banner5.png" alt="image3">
    <img class="lazy" data-src="./exam_banner5.png" alt="image3">
    <img class="lazy" data-src="./exam_banner5.png" alt="image3">
    <img class="lazy" data-src="./exam_banner5.png" alt="image3">
    <img class="lazy" data-src="./exam_banner5.png" alt="image3">
    <img class="lazy" data-src="./exam_banner5.png" alt="image3">
    <img class="lazy" data-src="./exam_banner5.png" alt="image3">
    ... <!-- 更多需要懒加载的图片元素 -->
  </div>

  <script>
    // 创建 Intersection Observer 实例
    const observer = new IntersectionObserver((entries, observer) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          // 将懒加载图像的 data-src 属性赋值给 src 属性
          entry.target.src = entry.target.dataset.src;

          // 停止观察已加载的图片
          observer.unobserve(entry.target);
        }
      });
    });

    // 获取所有需要懒加载的图片元素
    const lazyImages = document.querySelectorAll('.lazy');

    // 对每个图片元素添加观察者
    lazyImages.forEach(image => {
      observer.observe(image);
    });
  </script>
</body>
</html>

来自版权声明:本文为CSDN博主「一贱你就笑~」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值