IntersectionObserver 交叉观察者

91 阅读1分钟

IntersectionObserver 是浏览器提供的一个 API,用于异步观察目标元素与其祖先元素或顶级文档视窗的交叉状态。 用于页面图片类懒加载,或者列表滚动加载等。

  • 图片懒加载:当图片元素和视口出现交叉时,图片元素上的data-src赋值给src
  • 列表滚动加载:当列表底下的转圈spin动画和视口出现交叉时,调用接口获取下一页数据。

示例 Vue3.x

<script setup>
import { onMounted, ref } from 'vue'

const ob = new IntersectionObserver((entries) => { //  交叉观察者
  console.log('IntersectionObserver---entries', entries);
  for (const entry of entries) {
    if (entry.isIntersecting) { // 元素进入视口
      const target = entry.target
      target.src = new URL(`../../assets/images/${target.dataset.src}`, import.meta.url).href
      ob.unobserve(target) // 取消 交叉观察
    }
  }
}, {
  // root:null, // 参考根元素:Element | null   默认值: null  [必须是目标元素的祖先元素   指定为 null 或未指定,则使用浏览器视口作为根]
  // rootMargin: '10px', // string 用于扩大或缩小根元素root的边界框 [正值会扩大根元素的边界,负值会缩小]
  threshold: 0.5   // number 0-1  值为 0 表示目标元素刚进入/离开根元素时触发; 值为 1 表示目标元素完全进入根元素时触发
})

const imgs = ref([])
const setImgs = (el) => {
  imgs.value.push(el)
}

onMounted(() => {
  for (const img of imgs.value) {
    ob.observe(img) // 订阅 交叉观察
  }
})
</script>

<template>
  <div>
    <div style="height: 60vh; background-color: pink;" />
    <img
      v-for="item in 20"
      :key="item"
      :ref="(el) => setImgs(el)"
      style="width:200px; height: 200px; margin: 20px;"
      src="../../assets/images/default.png"
      data-src="05-27.jpg"
      alt=""
    >
  </div>
</template>