Intersection Observer API(交叉观察器)实现触底加载

1.Intersection Observer API简介

提供了一种异步检测目标元素与祖先元素或视口(可统称为根元素)相交情况变化的方法。简单来讲就是用来判断目标元素是否出现在视口中,然后进行一些特殊处理。
常见使用场景:图片懒加载,列表触底加载,内容无限滚动,目标元素进入视口进行动画播放等

2.为什么要使用该API

因为在如今网页开发的过程中,常常需要判断某个元素是否进入了"视口"(viewport),即用户能不能看到它。面对这种相交检测的任务时,过去我们通常会使getBoundingClientRect()等方法来获取相关元素的位置信息,并且还会用到事件监听。
然而事件监听和调用getBoundingClientRect()等 API 都是运行在主线程,因此频繁触发、调用会造成性能问题,而且这种检测方法使用起来比较繁琐。
因此官方就提出了Intersection Observer API,由于方法是异步的,不影响主线程的执行效率。

3.使用方法

1.实例化对象

var observer = new IntersectionObserver(callback, options);
callback:检测目标元素的回调函数
options:根元素配置项
该函数的返回值: 一个新的IntersectionObserver对像。

2.开始检测目标元素

let target = document.querySelector(“#target”); //目标元素
observer.observe(target); //开始监听该目标元素

4.触底加载示例

<template>
  <div class="container" id="container">
    <div class="item" v-for="(item, index) in dataSource" :key="index">{{ index }}-{{ item }}</div>
    <div id="footer">底部</div>
  </div>
</template>

<script setup lang="ts">
  import { onMounted, ref } from 'vue'
  // 初始值
  const dataSource = ref([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
  // 根元素配置项
  let options = {
    root: document.querySelector('#container'), //根元素
    rootMargin: '0px', //传值形式类似于css的margin 传一个值则四个边都为0
    threshold: 0 //触发条件 表示目标元素刚进入根元素时触发
  }
  //io 为 IntersectionObserver对象 - 由IntersectionObserver()构造器创建
  const initial = () => {
    var io = new IntersectionObserver(entries => {
      //entries 为 IntersectionObserverEntry对像数组
      entries.forEach(item => {
        //item 为 IntersectionObserverEntry对像
        // isIntersecting是一个Boolean值,判断目标元素当前是否可见
        if (item.isIntersecting) {
          //目标元素 可见时 进行相关操作
          console.log((item.target as any).innerText, '可见', '加载数据')
          setTimeout(() => {
            getData()
          }, 1000)
          // io.unobserve(item.target) //停止监听该div DOM节点
        } else {
          // 目标元素不可见时进行相关操作
          console.log((item.target as any).innerText, '不可见')
        }
      })
    }, options) //不传options参数就会默认根元素为浏览器视口
    const footer = document.querySelector('#footer') as Element
    io.observe(footer) // 监听 DOM节点
  }
  const getData = () => {
    // 加载数据:真实场景下为接口请求数据
    dataSource.value = [...dataSource.value, ...dataSource.value] as any
  }
  onMounted(async () => {
    initial()
  })
</script>

<style scoped>
  .read-the-docs {
    color: #888;
  }
  * {
    margin: 0;
    padding: 0;
  }
  .container {
    width: 500px;
    height: 400px;
    border: 1px solid #e5e5e5;
    overflow: auto;
  }
  .container > div {
    margin: 5px auto;
    width: 100px;
    height: 100px;
    outline: 1px solid red;
  }
</style>

5.参考文章

MDN Intersection Observer API
大白话详解Intersection Observer API
详解 Intersection Observer API ( 交叉观察器 )

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大兵的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值