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 ( 交叉观察器 )