大白话详解Intersection Observer API

昨日我写了Vue2 中自定义图片懒加载指令这篇博客,文章数据很好,阅览量能够上千,对于我这个刚写博客一周的新博主来说,是何等的荣幸。

所以在此我要感谢一切的读者与这个咱们庭,是你们肯定了我,让我有了学习和写博客的动力。

那现在就来更新今天的文章吧,持续连续昨日的文章,昨日的文章有朋友在谈论区推荐了Intersection Observer API来完成图片懒加载,那这篇博客我先介绍一下这 API,但这 API 兼容性一般,且彻底不兼容 IE,咱们在实践项目中谨慎运用。

但在介绍Intersection Observer API之前,首要要先了解别的三个知识点,分别是 IntersectionObserver()结构器,IntersectionObserverEntry 方针与IntersectionObserverEntry 方针。

他们之前的联系比较复杂,咱们能够先看看这个整体联系图,以及他们的参数、特点与办法。

大白话详解Intersection Observer API

1.Intersection Observer API 的根本介绍

Intersection Observer API供给了一种异步检测方针元素与祖先元素或视口(可统称为根元素)相交状况改变的办法。

  • 留意点: 由于该 API 是异步的,它不会跟着方针元素的翻滚同步触发,而IntersectionObserver API是通过requestIdleCallback()完成,即只有浏览器空闲下来,才会执行调查器。这意味着这个调查器的优先级非常低。

1.1 Intersection Observer API 出现的原因

由于在如今网页开发的过程中,常常需求判别某个元素是否进入了”视口”(viewport),即用户能不能看到它。

面对这种相交检测的使命时,曩昔咱们通常会运用Element.getBoundingClientRect()等办法来获取相关元素的方位信息,而且还会用到事情监听

然而事情监听和调用Element.getBoundingClientRect()等 API 都是运转在主线程,因而频频触发、调用会造成功能问题,而且这种检测办法运用起来比较繁琐

因而官方就提出了Intersection Observer API,该 API 的出现就是为了高效的处理以下两大类问题:

  1. 某个元素是否可见,如:
    • 图片懒加载——当图片翻滚到可见时才进行加载
    • 内容无限翻滚——当用户翻滚到接近底部时直接加载更多,而无需翻页,给用户一种网页能够无限翻滚的错觉
  2. 两个元素是否相交,如:
    • 检测广告的曝光状况——为了核算广告收益,需求知道广告元素的曝光状况
    • 在用户看见某个区域时执行使命或播放动画

Intersection Observer API会注册一个回调函数,只会在以下两种状况触发:

  1. 方针元素进入或退出根元素
  2. 穿插比达到阈值时,补充点:
    • 但是该 API 无法供给堆叠的像素个数或详细哪个像素堆叠,只能设置阈值来进行操控回调函数的调用。

这样,浏览器的主线程就不用在监听元素是否相交,而且IntersectionObserver API是异步进行检测的,也不会占用主线程的资源,从而功能上得到了提升。

1.2 Intersection observer 的重要概念

Intersection observer API 有以下五个重要的概念:

  1. 方针(target)元素 — 咱们要监听的元素
  2. 根(root)元素 — 协助咱们判别方针元素是否契合条件的元素 以下两种状况根元素会默以为尖端文档的视口(一般为 html)。
    • 方针元素不是可翻滚元素的子孙且不传值时
    • 指定根元素为 null
  3. 穿插比(intersection ratio)—方针元素与根根的交集相对于方针元素百分比的表明(取值规模 0.0-1.0)。
  4. 阈值(threshold) — 回调函数触发的条件。
  5. 回调函数(callback) — 为该 API 装备的函数,会在设定的条件下触发。

2.IntersectionObserver()结构器

IntersectionObserver()结构器用于创立一个 IntersectionObserver 方针,并会将该对像进行放回。 该结构器函数的装备参数如下图所示:

大白话详解Intersection Observer API

其语法如下:

var observer = new IntersectionObserver(callback[, options]);

2.1 IntersectionObserver()结构器的参数与回来值

首要咱们先了解一下IntersectionObserver()结构器的参数,其参数有:

  • callback(必选参数) — 当穿插比超越指定阈值触发回调函数,此函数可接受两个参数:

    1. entries — 由IntersectionObserverEntry方针组成的数组 但每个被触发的阈值,都或多或少与指定阈值有误差。
    2. observer — 回来被调用的IntersectionObserver实例。
  • options(可选参数) — 用于装备回调函数触发的条件,其参数下还有三个子参数:

    1. root — 指定根元素。用于查看方针的可见性。默以为浏览器视口
      • 假如指定为 null,也为浏览器视口。
      • 有必要是方针元素的父级元素。
    2. rootMargin — 根元素的扩缩边距。其传值形式与 CSS 中 margin 相同,用于操控根元素每一边的扩缩(单位为 px 或%),从而操控核算根元素和方针元素的交集的区域规模,默许值为 0
    3. threshold — 阈值,回调函数触发的条件。取值规模为 0.0-1.0,默许值为 0.0
      • 当传入数值类型时,只会触发一次。
      • 当传入数组类型时,可触发多次。
        • 如:[0,0.25,0.5,0.75,1]表明方针元素在跟元素的可见程度每多 25% 就执行一次回调
  • 该函数的回来值: 一个新的IntersectionObserver对像。

    • 该方针会依照设定的阈值来监听方针元素。
    • 调用自身的observe()办法开端对方针元素进行监听。

2.2 IntersectionObserver()结构器的根本语法与反常信息

运用 IntersectionObserver()结构器创立 IntersectionObserver 方针并进行监听的语法如代码下所示:

let options = {
  root: document.querySelector("#root"), //根元素
  rootMargin: "0px", //传值形式相似于css的margin 传一个值则四个边都为0
  threshold: 0, //触发条件 表明方针元素刚进入根元素时触发
};
//IntersectionObserver方针
let observer = new IntersectionObserver(callback, options);
let target = document.querySelector("#target"); //方针元素
observer.observe(target); //开端监听该方针元素
  • 两种反常类型:
    • SyntaxError — 指定的 rootMargin 不存在或不契合语法。
    • RangeError — 一个或多个阈值超出了 0.0 到 1.0 的规模。

3.IntersectionObserver 方针

IntersectionObserver 接口(从属于Intersection Observer API)供给了一种异步调查方针元素根元素 穿插状况的办法。

当 IntersectionObserver 方针被创立时,就会被指定所监听的根元素、阀值等信息。一旦 IntersectionObserver 被创立后就无法更改其指定信息。

  • 所以一个给定的调查者方针只能用来监听可见区域的特定改变值;当然你也能够在同一个调查者方针中装备监听多个方针元素。

该方针的特点与办法如下图所示:

大白话详解Intersection Observer API

3.1 IntersectionObserver 方针的特点与办法

3.1.1 三个特点

该对像的三个特点与IntersectionObserver()结构器的 options 参数相似,而且这三个特点都只能读取操作,不能进行更改。

特点 阐明 默许值
root 指定根元素。假如传值为 null,则为尖端文档的视窗。 尖端文档的视口(一般为 html)
rootMargin 根元素的扩缩边距。其传值形式与 CSS 中 margin 相同,用于操控根元素每一边的扩缩(单位为 px 或%),从而操控核算根元素和方针元素的交集的区域规模。单位为 px 或%。默 “0px 0px 0px 0px”
thresholds 一个包含阈值的数组,并按升序摆放,列表中的每个阈值都是监听方针的穿插区域与边界区域的比率。当监听方针的任何阈值被越过期,都会触发回调函数。 0

3.1.2 四个办法

该方针的四个办法如下表:

办法 阐明
observe(target) 开端监听指定方针元素
unobserve(target) 中止监听指定的方针元素
takeRecords() 回来一切调查方针的 IntersectionObserverEntry 方针数组
disconnect() 使 IntersectionObserver 方针中止全部监听作业

4. IntersectionObserverEntry 方针

IntersectionObserverEntry接口(从属于 Intersection Observer API)描绘了方针元素与其根元素容器在某一特定过渡时刻的穿插状况。

IntersectionObserverEntry对像数组作为entries参数传递给IntersectionObserver对像的回调函数中; 此外,这方针数组只能通过调用IntersectionObserver.takeRecords()来获取。

该方针的主要特点如下图所示:

大白话详解Intersection Observer API

4.1 IntersectionObserverEntry 方针的特点

IntersectionObserverEntry 方针的七个特点都是只读特点,如下表所示:

特点 阐明
target 回来方针元素,表明现在该方针正监听的元素
isIntersecting 回来一个布尔值,方针元素刚出现在根元素可视区时回来 true;方针元素从根元素可视区消失回来 false;以上两种状况都会触发 callback 函数
boundingClientRect 回来方针元素的矩形区域的信息,回来结果与element.getBoundingClientRect()相同
rootBounds 回来根元素的矩形区域的信息,getBoundingClientRect()办法的回来值,假如没有根元素(即直接相对于视口翻滚),则回来 null
intersectionRect 回来方针元素与视口(或根元素)的穿插区域的信息
intersectionRatio 回来方针元素的可见份额,即intersectionRectboundingClientRect的份额,彻底可见时为 1,彻底不行见时小于等于 0
time 回来一个记载从IntersectionObserver的时刻原点到穿插被触发的时刻的时刻戳

5. Intersection Observer API 的兼容性

该 API 的兼容性如下:

大白话详解Intersection Observer API
详情咱们可参阅CAN I USE – intersectionobserver。

6. Intersection Observer API 的简单案列

咱们能够在自己电脑运转一下下面的代码,会有更深的了解。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      .container > div {
        margin: 5px auto;
        width: 100px;
        height: 100px;
        outline: 1px solid red;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
      <div class="item">4</div>
      <div class="item">5</div>
      <div class="item">6</div>
      <div class="item">7</div>
      <div class="item">8</div>
      <div class="item">9</div>
      <div class="item">10</div>
      <div class="item">11</div>
      <div class="item">12</div>
      <div class="item">13</div>
      <div class="item">14</div>
      <div class="item">15</div>
    </div>
    <script>
      //io 为 IntersectionObserver方针 - 由IntersectionObserver()结构器创立
      var io = new IntersectionObserver((entries) => {
        //entries 为 IntersectionObserverEntry对像数组
        entries.forEach((item) => {
          //item 为 IntersectionObserverEntry对像
          // isIntersecting是一个Boolean值,判别方针元素当时是否可见
          if (item.isIntersecting) {
            //div 可见时 进行相关操作
            console.log(item.target.innerText);
            io.unobserve(item.target); //中止监听该div DOM节点
          }
        });
      }); //不传options参数,默许根元素为浏览器视口
      const divArr = [...document.querySelectorAll(".item")];
      divArr.forEach((div) => io.observe(div)); // 遍历监听一切div DOM节点
    </script>
  </body>
</html>

我已在 Vue2 运用Intersection Observer API完成了图片懒加载作用哦,咱们能够去看看。Vue2 中自定义图片懒加载指令 2.0

参阅博客

  • MDN – Intersection Observer API
  • MDN – IntersectionObserver.IntersectionObserver()
  • MDN – Intersection Observer
  • MDN – IntersectionObserverEntry
  • 超好用的 API 之 IntersectionObserver
  • 阮一峰 – IntersectionObserver API 运用教程

结语

这是我现在所了解的知识面中最好的解答,当然也有或许存在一定的误区。

所以假如对本文存在疑问,能够在谈论区留言,我会及时回复的,欢迎咱们指出文中的错误观点。

最后码字不易,觉得有协助的朋友点赞、保藏、重视走一波。