使用 JavaScript 的 Intersection Observer API 显示滚动内容
你是否曾经访问过这样一个网站,当你向下滚动页面时,网页的内容会在你接近它们的时候逐渐显示出来?你必须承认,这是一个非常时髦的功能。您是否曾经

你是否曾经访问过这样一个网站,当你向下滚动页面时,网页的内容会在你接近它们的时候逐渐显示出来?你必须承认,这是一个非常时髦的功能。您是否曾经想过如何在不使用第三方库或插件的情况下在您的项目中实现这一特性?当然,JavaScript 有一个原生的 Intersection Observer API,可以让你做到这一点... ... 还有更多。在本文中,我们将讨论这个 Intersection Observer API 如何工作,以及如何通过构建一个简单的 web 页面来实现这个“在滚动中显示内容”特性,从而使用它来检测元素的可见性。
什么是交叉观察者?
Intersection Observer API 是一种观察(监视) DOM 中某个元素相对于另一个根元素的位置和可见性的新方法,并且在这些元素相交时运行回调函数
现在您可能想知道,根元素到底是什么?根元素只是作为其他元素的父元素或容器元素的元素。这意味着,如果我们在 HTML 文档中创建一个 div,在这个 div 中放置一个 p text,那么 div 就成为 p text 的直接根元素(父元素) ,因为它包含段落
html
<body>
<div>
<p>Lorem, ipsum.</p>
</div>
</body>
基于这个逻辑,我们可以放心地说,body 也是这个 div 的直接父元素,也是 p 文本的祖父元素。但是您知道 DOM 中所有东西的祖先根元素还有什么吗?浏览 HTML 文件的浏览器会成为网页上任何时间浏览器的视窗(萤幕)可见区域的一个容器(根)
因此,从本质上讲,Intersection Observer API 可以用来观察一个元素,以查看该元素是否与 DOM 中的根元素相交(相遇或穿越) ,或者它是否只是进入或离开浏览器的视口。并且当这个事件发生时,观察者可以触发一个回调函数
注意: 回调函数只是作为另一个函数的参数(其参数的实际值)提供给该函数的普通函数

创建基本的 HTML/CSS 页面
已经知道了 Intersection Observer 是什么,那么让我们深入研究它的实现。我们将从创建一个简单的 HTML 页面开始,包含3个部分,第一部分和第三部分对我们来说没什么意思,因为我们将主要处理第二部分,我们只是想要更多的空间来滚动页面
html
<body>
<section class="section-1">
<h2>Section 1</h2>
</section>
<section class="section-2">
<img class="img" src="background.jpg" alt="" />
</section>
<section class="section-3">
<h2>Section 3</h2>
</section>
</body>
现在对于 CSS,我们将给每个区段一个高度为100vh,使用 flex 将每个区段的内容居中,然后给图像一个固定的响应宽度,并通过应用背景颜色将每个区段分开,使每个区段显而易见。最后,我们将创建一个隐藏类,它将负责在稍后使用 JavaScript 隐藏和显示我们的内容
css
h2 {
font-size: 3rem;
}
.img {
width: 95%;
max-width: 600px;
transition: all 1.5s ease-in;
}
section {
background-color: #dbe6eb;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.section-2 {
background-color: #fff;
}
.hidden {
opacity: 0;
transform: translateX(100%);
}

最终的布局很好,我们已经设置好了基本的网页,现在让我们深入到 JavaScript 中来讨论 Intersection Observer。
Intersection Observer API
要使用交叉观察者 API,我们首先需要使用它的默认对象构造函数创建一个
js
new IntersectionObserver();
这个构造函数基本上是 JavaScript 中的一个内置函数,它负责创建一个观察者,然后我们可以使用它来观察我们的目标元素,这个构造函数有两个参数,它们包含两个参数
第一个参数是一个回调函数,当与被观察的元素有交集时调用该函数。还记得什么是回调函数吗?只是一个普通的函数,作为函数参数传递给另一个函数,所以基本上交叉观察者被赋予一个函数,当有交叉时调用
第二个参数是一个包含用于自定义观察器的选项的对象。这个参数实际上是可选的,可以省略,如果没有提供观察者将使用其默认选项(稍后将详细介绍)。现在让我们创建一个交叉观察器。
首先,让我们选择要观察的目标元素
js
const section = document.querySelector(‘.section-2’);
然后让我们创建一个观察者来观察这个 section 元素
j
Const theObserver = IntersectionObserver(callbackFunction, options);
一旦我们创建了一个观察者,我们就必须使用观察者上的内置 observe ()方法告诉观察者要观察的目标元素。此方法接收要作为其参数观察的目标元素。我们就这么做吧
j
theObserver.observe(section);
让我们回顾一下刚才所做的,我们首先选择要观察的目标元素,然后创建一个观察者观察者,最后我们通过使用 observe ()方法将要观察的目标元素传递给观察者,告诉观察者要观察什么。就是这样,我们已经设置好了一切,唯一的问题是我们既没有定义 callbackFunction,也没有定义 options 对象,所以它们目前还没有定义
完整代码
js
const section = document.querySelector(".section-2");
const imgContent = document.querySelector(".img");
const objOptions = {
root: null,
threshold: 0.3,
rootMargin: "-100px",
};
const sectionObserver = new IntersectionObserver(callBackFunction, objOptions);
sectionObserver.observe(section);
function callBackFunction(entries) {
const [entry] = entries;
console.log(entry);
if (entry.isIntersecting) {
imgContent.classList.remove("hidden");
} else {
imgContent.classList.add("hidden");
}
}
IntersectionObserverEntry提供观察元素的信息,有七个属性
懒加载
js
const io = new IntersectionObserver(()=>{ // 实例化 默认基于当前视窗
})
let ings = document.querySelectorAll('[data-src]') // 将图片的真实url设置为data-src src属性为占位图 元素可见时候替换src
function callback(entries){
entries.forEach((item) => { // 遍历entries数组
if(item.isIntersecting){ // 当前元素可见
item.target.src = item.target.dataset.src // 替换src
io.unobserve(item.target) // 停止观察当前元素 避免不可见时候再次调用callback函数
}
})
}
imgs.forEach((item)=>{ // io.observe接受一个DOM元素,添加多个监听 使用forEach
io.observe(item)
})
boundingClientRect 目标元素的矩形信息
intersectionRatio 相交区域和目标元素的比例值 intersectionRect/boundingClientRect 不可见时小于等于0
intersectionRect 目标元素和视窗(根)相交的矩形信息 可以称为相交区域
isIntersecting 目标元素当前是否可见 Boolean值 可见为true
rootBounds 根元素的矩形信息,没有指定根元素就是当前视窗的矩形信息
target 观察的目标元素
time 返回一个记录从IntersectionObserver的时间到交叉被触发的时间的时间戳
来自翻译计划
作者:羊先生
https://dev.to/daveyhert/a-beginner-s-guide-to-the-intersection-observer-api-2d50