JavaScript 介绍Intersection Observer
Intersection Observer 是一个用于检测目标元素与其祖先元素或文档视口之间交互的API。例如,如果我们想要检测某个元素是否在视口中可见,我们可以使用此API。
Intersection Observer的一些用例包括:
- 懒加载图片。
- 检测元素是否在视口中可见。
- 如果在视口中,则自动播放视频,否则暂停视频。
- 无限滚动。
如何使用Intersection Observer?
Intersection Observer API可以用于观察一个元素。该API接受两个输入:
- 回调函数: 此函数接收一个由祖先或文档视口观察的条目(元素)列表。该条目列表具有属性isIntersecting,可用于确定目标条目是否可见。如果此属性返回true,则表示目标可见;否则为不可见。
- 具有属性root、threshold和rootMargin的对象。
- root 属性用于指定用作检查目标元素可见性的视口元素。它必须是目标元素的祖先,如果未指定,则默认为文档视口。
- threshold 属性可以是一个数字或数字数组。它用于指定当上面的回调函数触发时,目标元素应该可见的程度。例如,如果阈值为0.5,则当目标元素的一半可见于视口时,回调函数将被触发;如果阈值为[0.5, 0.25],则当目标元素的一半和四分之一部分可见时,回调函数将被触发。默认值为0,即目标元素一旦可见,回调函数将被触发。
- rootMargin 属性与CSS的margin属性相同,可以接受一个值(应用于所有四个边距)或多个值(适用于各个边距)。该属性可用于扩大或缩小容器视口。例如,如果rootMargin为20px,视口将增大20px,因此,一旦目标元素距离视口内部20px,它将被视为相交。边距的默认值为0。
此API返回一个对象,其中有一个observe属性,可用于观察我们所需的目标元素。
让我们通过一个例子来了解这个API是如何工作的。
问题陈述: 我们会有一个 div 元素(这将是我们的 目标 元素),其中包含在一个可滚动的div容器中一些段落元素。我们还会有另一个按钮,当点击时会显示一个警报框,告诉我们目标元素是否在容器div中可见。
方法:
1. 我们将创建一个带有类名 container 的div,并在 container div内添加一些段落元素和另一个带有类名 target 的div。容器div将充当我们的 根 元素。此外,我们将创建一个 按钮 ,点击该按钮将显示 警报框 ,并声明一个变量 isVisible ,用于存储目标是否可见的信息。
const container = document.querySelector(".container");
const target = document.querySelector(".target");
const btn = document.querySelector(".btn");
let isVisible = null;
2. 将 container div设置为根元素,并将阈值设置为 1 ,这意味着每当 target div完全可见在 container div内时, isIntersecting 属性将为 true。
const options={
root: container,
threshold: 1
}
3. 创建一个 回调 函数,该函数将设置 isVisible 的值。由于只有一个将被观察的元素,因此我们将访问 entries[0] 。
const callBack = (entries) => {
isVisible = entries[0].isIntersecting;
};
4. 现在我们将使用 Intersection Observer API 并将以上的 回调函数 和 选项 对象作为输入
const observer = new IntersectionObserver(callBack,options);
5. API返回的对象将用于观察按钮元素。
observer.observer(target)
6. 现在我们将为按钮添加一个点击事件监听器,当该按钮被点击时,它将显示一个警告框,其中包含目标元素是可见还是不可见的信息,具体取决于目标元素是否可见。
btn.addEventListener("click", () => {
if (isVisible) {
alert("Target Element is visible");
}else {
alert("Target Element is not visible");
}
});
HTML
<!DOCTYPE html>
<html>
<head>
<title>Intersection Observer</title>
<meta charset="UTF-8" />
<link rel="stylesheet" href="./src/styles.css" />
</head>
<body>
<div>
<div class="container">
<div class="content">
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<div class="target"></div>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
<p>GeeksforGeeks</p>
</div>
</div>
<button class="btn">
Check If Target Is Visible
</button>
</div>
<script src="src/index.js"></script>
</body>
</html>
CSS
body {
font-family: sans-serif;
display: flex;
justify-content: center;
}
.container {
height: 300px;
width: 200px;
background-color: ghostwhite;
border: 1px solid black;
overflow-y: scroll;
display: flex;
flex-direction: column;
}
.content {
color: green;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.target-btn {
padding: 8px;
font-size: 20px;
cursor: pointer;
color: green;
}
.target {
height: 100px;
width: 100px;
background-color: green;
}
.btn {
margin-top: 20px;
padding: 20px;
cursor: pointer;
}
Javascript
const target = document.querySelector(".target");
const container = document.querySelector(".container");
const btn = document.querySelector(".btn");
let isVisible = null;
const callBack = (entries) => {
isVisible = entries[0].isIntersecting;
};
const options = {
root: container,
threshold: 1
};
const observer = new IntersectionObserver(callBack, options);
observer.observe(target);
btn.addEventListener("click", () => {
if (isVisible) {
alert("Target Element is visible");
} else {
alert("Target Element is not visible");
}
});
输出:
说明: 每当我们点击按钮时,它会告诉我们目标元素是否在容器div内,但只有当它完全可见时才会告诉我们,因为我们将阈值设置为1。