1. 前言
在项目中的很多需求中,经常会遇到一些关于一些元素是否在可视区域的判定,关于这个情况的判断有很多种办法,例如可以通过可视区域的尺寸与向上滚动的尺寸再加上当前监听的dom元素所在的位置,就可以计算得出这个dom元素是否在可视区域,但是有很严重的问题就是,使用起来太麻烦了
2. IntersectionObserver API介绍
关于IntersectionObserver API的更详细的介绍,可以去参见MDN,以下只是简单介绍一些这个API
IntersectionObserver可以使用observe方法来对指定的dom元素进行监听是否在可视区域中,如果监听的dom元素进入了可视区域,就会触发IntersectionObserver中的回调函数,回调函数中携带一个参数,这个参数是一个数组,数组中的每个元素,就是已经进入了可视区域的dom元素
3. 使用示例
<!--
* @Author:WangZhiYu
* @Date: 2023/07/11 20:46:00
* @LastEditors: wangzhiyu
* @LastEditTime: 2023-07-11 21:19:13
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.container {
width: 1100px;
margin: 0 auto;
}
.item {
height: 400px;
background-color: blue;
margin: 20px 0;
color: #fff;
}
</style>
</head>
<body>
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<script>
// 使用intersection observer API来监听那些元素进入/退出了视口
const ob = new IntersectionObserver(
entries => {
// console.log(entries, 'entries');
// 所有监听的dom,以数组的方式呈现,其中属性target表示当前监听的元素,isIntersecting表示是否与视口交叉
console.log(entries.filter(item => item.isIntersecting));
// 获取所有在视口中的元素
let interSectingArr = entries.filter(item => item.isIntersecting);
// 循环元素并且进行内容填充操作
interSectingArr.forEach(item => {
item.target.textContent = '进入了视口';
// 取消监听
ob.unobserve(item.target);
});
},
// intersectionObcserver的配置
{
// 表示元素和哪个元素交叉时会触发,默认值为null,也就是浏览器窗口
root: null,
// 可以通过配置rootMargin来延伸交叉的距离值,默认是一个盒子到达浏览器窗口就算交叉,配置了rootMargin为10之后就是盒子距离浏览器窗口为10px的时候就算交叉了
// rootMargin: '10px',
// 表示交叉的阈值,取值为:0-1,如果设置为0.5就表示监听的元素进入一半的时候就开始监听
threshold: 0.1,
}
);
// 获取所有要监听视口的dom并循环使用observeAPI监听
let list = document.querySelectorAll('.item');
list.forEach(item => {
// 使用observe监听dom元素是否进入视口
ob.observe(item);
});
</script>
</body>
</html>