服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服务器之家 - 编程语言 - JavaScript - js教程 - Intersection Observer交叉观察器示例解析

Intersection Observer交叉观察器示例解析

2023-05-23 15:01完锤子 js教程

这篇文章主要为大家介绍了Intersection Observer交叉观察器示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

前言

作为一个前端搬砖仔,偶尔会遇到关于视窗的问题...

其中就经常会遇到一些数据上报问题,比如某某组件是否被用户看到了,如果看到就要上报数据,让产品同学方便进行数据分析。

分析这个场景可以发现,必须要用户看到了我才能上报,怎么判断用户是否看到了这个组件呢?

传统的方法是操作dom,通过这些数据或方法(offsetTop、scrollTop,getBoundingClientRect)来进行比较。

频繁的对DOM状态的计算,会造成不小的性能损耗,导致页面卡顿。

接下来介绍一种我最近比较常用的新方式:Intersection Observer(交叉观察器)

Intersection Observer 翻译过来即交叉观察器

主要是用于监听目标元素与指定的元素视窗是否发生交叉

一句话总结:Intersection Observer API 提供了一种异步检测目标元素与祖先元素或 viewport 相交情况变化的方法。 – MDN

使用

一、利用IntersectionObserver构造函数创建一个观察器实例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
  <div class="home"></div>
</template>
<script>
export default {
  name: "HomeView",
  mounted() {
    // 可见性发生变化后的回调
    function callback() {
      console.log("触发了");
    }
    // 交叉观察器配置项
    let options = {};
    // 生成交叉观察器
    const observer = new IntersectionObserver(callback);
  },
};
</script>

(callback是当元素可见比例超过指定阈值后会调用的一个回调函数,options是一个可以用来配置 observer 实例的对象。)

输出一下IntersectionObserver构造函数返回的实例

Intersection Observer交叉观察器示例解析

实例属性:

root:root 属性用来获取当前 intersectionObserver 实例的根元素,用于判断元素是否可见区域。

(注:这个既可以是 target 元素祖先元素也可以是指定 null 则使用浏览器视口 做为容器 (root)。)

rootMargin:一个类似于margin的字符串参数,就可以使用 root margin 来调整根矩形大小。

(注:由于使用Intersection Observer的过程中所有区域均被当做一个矩形看待,因此当我们需要调整元素边界的矩形时,用 root margin 来调整大小。)

threshold:阈值,可以传一个0 ~ 1的number,也可以传个0 ~ 1范围的number数组。

(注:如果传一个0 ~ 1的number,如0.5则说明,目标元素和root相交超过50%时,即二者重合超过目标元素的50%时,触发回调,如果是一个数组[0.1, 0.2, 0.5]则分别在10% 20% 50%处触发回调)

二、观察器实例监听元素相交

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<template>
  <div class="home">
    <div id="target" class="target-item"></div>
  </div>
</template>
<script>
export default {
  name: "HomeView",
  mounted() {
    // 可见性发生变化后的回调
    function callback(data) {
      console.log("触发了");
      console.log(data);
    }
    // 交叉观察器配置项
    let options = {};
    // 生成交叉观察器
    const observer = new IntersectionObserver(callback);
    // 获取目标节点
    let target = document.getElementById("target");
    // 监听目标元素
    observer.observe(target);
  },
};
</script>
<style scoped>
.home {
  height: 300vh;
}
.home .target-item {
  margin-top: 120vh;
  width: 20px;
  height: 20px;
  background: #000;
}
</style>

可以看到

Intersection Observer交叉观察器示例解析

通过滚动,可以不停监听到观察器的回调。

三、观察器回调函数参数

看到在观察器的回调中是返回了一个对象的,修改原来的回调函数,对应看看到底返回了啥?

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
export default {
  name: "HomeView",
  mounted() {
    // 可见性发生变化后的回调
    function callback(data) {
      console.log("触发了");
      data.map((item) => {
        // 目标元素的getBoundingClientRect的返回值。
        console.log(item.boundingClientRect);
        // 目标元素和根元素交叉区域的getBoundingClientRect的返回值。
        console.log(item.intersectionRatio);
        // 目标元素的可见比例,相当于二者重合了多少。
        console.log(item.intersectionRect);
        // 目标元素与根元素是否相交
        console.log(item.isIntersecting);
        // 根元素的getBoundingClientRect的返回值
        console.log(item.rootBounds);
        // 目标元素,是个dom
        console.log(item.target);
        // 从首次创建观察者到触发指定阈值发生交叉的时间
        console.log(item.time);
      });
    }
    // 交叉观察器配置项
    let options = {
      threshold: 0.5,
    };
    // 生成交叉观察器
    const observer = new IntersectionObserver(callback, options);
    // 获取目标元素
    let target = document.getElementById("target");
    // 监听目标元素
    observer.observe(target);
  },
};

可以看到控制台输出了下述内容:

Intersection Observer交叉观察器示例解析

可以看到返回了很多东西

其中就有我们熟悉的元素的getBoundingClientRect属性。

回调参数属性:

boundingClientRect: 对象,返回了目标元素的getBoundingClientRect的返回值。

intersectionRatio:对象,返回了目标元素和根元素交叉区域的getBoundingClientRect的返回值。

intersectionRect: 数字,目标元素的可见比例,相当于二者重合了多少。

isIntersecting: 布尔值,目标元素与根元素相交是否相交

(如果相交,则返回 true ,若为true则说明至少到达了一个阈值,如果为false,说明目标元素在阈值范围内不可见)

rootBounds: 对象,返回了根元素的getBoundingClientRect的返回值。

target:对象,目标元素,是个dom

time: 数字,从首次创建观察者到触发指定阈值发生交叉的时间

因此通过观察器的回调参数可以做到精确监听目标的,通过这些参数可以更好的支持如下拉加载技术上报等场景,由于该属性是原生api因此比起频繁的操作dom会来的更丝滑。

四、观察器的实例方法

通过上文我们已经说明了,如何使用交叉观察器,并介绍了观察器的实例属性及回调参数

下面说一下观察器的实例方法!

?
1
2
3
4
5
6
// 生成交叉观察器
const observer = new IntersectionObserver(callback, options);
// 获取目标元素
let target = document.getElementById("target");
// 监听目标元素
observer.observe(target);

可以看到监听目标元素的时候用了 observe 方法,这就是观察器的实例方法之一—— 监听目标元素

观察器的实例方法一共有四个

disconnect:停止对所有的目标元素的观察

observe:监听目标元素(可监听多个)

takeRecords:返回一个IntersectionObserverEntry对象数组(观察器回调参数就是这个),里面存放的各个目标元素的相交信息

unobserve:停止对一个指定目标元素的观察

通过代码来演示下上述方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<template>
  <div class="home">
    <div id="target1" class="target1-item"></div>
    <div id="target2" @click="unobserve()" class="target2-item"></div>
    <div style="margintop: 10px" @click="disconnect">disconnect</div>
  </div>
</template>
<script>
export default {
  name: "HomeView",
  data() {
    return {
      observer: {},
    };
  },
  mounted() {
    // 可见性发生变化后的回调
    function callback(data) {
      console.log(data[0].target.id);
    }
    // 生成交叉观察器
    this.observer = new IntersectionObserver(callback);
    // 获取目标元素1
    let target1 = document.getElementById("target1");
    // 获取目标元素2
    let target2 = document.getElementById("target2");
    // 监听目标元素1
    this.observer.observe(target1);
    // 监听目标元素2
    this.observer.observe(target2);
  },
  methods: {
    unobserve() {
      let target2 = document.getElementById("target2");
      // 停止监听目标元素2
      this.observer.unobserve(target2)
    },
    disconnect() {
      // 停止监听所有目标元素
      this.observer.disconnect();
    },
  },
};
</script>

代码效果如下所示:

Intersection Observer交叉观察器示例解析

可以看到一开始是监听元素1和元素2,接着停止元素2的监听,最后停止所有元素的监听

以上就是Intersection Observer(交叉观察器)的基本使用了。

五、总结

(1)利用IntersectionObserver构造函数创建一个观察器实例,设置其回调和基本参数

?
1
2
3
4
5
// 可见性发生变化后的回调
function callback() {
}
// 生成交叉观察器
this.observer = new IntersectionObserver(callback);

(2)获取目标元素节点,并监听该元素

?
1
2
3
4
// 获取目标元素
let target = document.getElementById("target");
// 监听目标元素
this.observer.observe(target);

(3)回调中处理相关逻辑

?
1
2
3
function callback(data) {
    console.log(data)
}

(4)观察器使用结束后,取消对元素的监听

?
1
2
3
4
// 停止观察某个目标元素
observer.unobserve(target);
// 关闭监视器
observer.disconnect();

聊聊Intersection Observer各大浏览器的支持性 截图自

Intersection Observer交叉观察器示例解析

总的来说,这个还是适用于很多浏览器的。

各位前端朋友,如果以后有遇到下拉加载或数据上报的场景的话不妨使用一下这个Intersection Observer

确实是一个开发的好工具。

以上就是Intersection Observer交叉观察器示例解析的详细内容,更多关于Intersection Observer交叉观察器的资料请关注服务器之家其它相关文章!

原文链接:https://juejin.cn/post/7200681438315315261

延伸 · 阅读

精彩推荐
  • js教程Selenium执行JavaScript脚本的方法示例

    Selenium执行JavaScript脚本的方法示例

    这篇文章主要介绍了Selenium执行JavaScript脚本的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友...

    测试开发小记6652021-12-23
  • js教程聊一聊六个JavaScript图表库

    聊一聊六个JavaScript图表库

    作为一名前端 Web 开发人员,能够像制作漂亮的交互式网页一样多地可视化数据是一项很棒的技能。这些 JavaScript 库使这项任务变得更容易,因为开发人员...

    粤嵌教育6652022-01-12
  • js教程如何在微信小程序中使用less详解(最优方式)

    如何在微信小程序中使用less详解(最优方式)

    这篇文章主要给大家介绍了关于如何在微信小程序中使用less(最优方式)的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的...

    九旬10442022-02-16
  • js教程nestjs返回给前端数据格式的封装实现

    nestjs返回给前端数据格式的封装实现

    这篇文章主要介绍了nestjs返回给前端数据格式的封装实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋...

    水痕018992022-01-22
  • js教程JavaScript 声明私有变量的两种方式

    JavaScript 声明私有变量的两种方式

    这篇文章主要介绍了JavaScript 声明私有变量的两种方式,帮助大家更好的理解和学习使用JavaScript,感兴趣的朋友可以了解下...

    _Fatman3732022-01-17
  • js教程微信小程序使用视频播放器video组件

    微信小程序使用视频播放器video组件

    这篇文章主要为大家详细介绍了微信小程序使用视频播放器video组件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一...

    柚子·小哥哥6612022-03-09
  • js教程js制作提示框插件

    js制作提示框插件

    这篇文章主要介绍了js制作提示框插件的方法,帮助大家更好的理解和使用js,感兴趣的朋友可以了解下...

    lanshanxiao10322021-12-18
  • js教程js定时器出现第一次延迟的原因及解决方法

    js定时器出现第一次延迟的原因及解决方法

    在本篇文章里小编给大家整理的是一篇关于js定时器出现第一次延迟的原因及解决方法,对此有需要的朋友们可以学习下。...

    宋宋大人5062021-12-24