使用 IntersectionObserver 检查页面是否滚动到特定位置

Avatar of Chris Coyier
Chris Coyier on

DigitalOcean 为您的旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费信用额度!

当网页滚动时,这是一个 DOM 事件。 我可以使用 window.scrollY 随时了解窗口滚动了多远。 我可以 监听 此事件并获取该数字

window.addEventListener("scroll", () => {
  console.log(window.scrollY)
});

假设我想知道用户是否向下滚动 100 像素或更多。 我可以通过查看 window.Y > 100 来测试。 在这里,我会记录我们是否满足条件

window.addEventListener("scroll", () => {
  if (window.scrollY < 100) {
    console.log("Not past 100px");
  } else {
    console.log("Past 100px!");
  }
});

但这有点违反模式。 它简单、易懂,并且有效,但它有点糟糕。 它很糟糕,因为它触发频率很高。 当用户向下滚动页面时,它很容易触发数十次、数百次甚至 *数千次*。 每次触发时,我们都必须在 JavaScript 的至关重要的单线程上执行一些 JavaScript 代码。 这意味着更多时间用于计算滚动相关内容,而更少时间用于执行其他重要操作。

有一些方法可以减少这种密集操作,并且自然地,这些方法非常不错。 节流和防抖是 JavaScript 中用于提高性能的好模式。 它们略有不同,因此这里有一个解释,以及一些 演示。 它们的要点是防止大量 JavaScript 代码执行,直到您需要它们执行。

但是,有一个更好的方法。

还有另一个原生浏览器功能称为 IntersectionObserver,它允许您观察一个元素,并且只有在发生重要事件时才会执行 JavaScript 代码,例如当它进入或离开视窗时。

所以诀窍是:我们在页面上放置一个 1 像素 × 1 像素的像素元素并观察它。 以下是放置位置

<div id="pixel-to-watch"></div>
#pixel-to-watch {
  position: absolute;
  width: 1px;
  height: 1px;
  top: 100px;
  left: 0;
}

以下是观察方式

let observer = new IntersectionObserver(entries => {
  console.log(entries);
  if (entries[0].boundingClientRect.y < 0) {
    console.log("Past 100px!");
  } else {
    console.log("Not past 100px");
  }
});
observer.observe(document.querySelector("#pixel-to-watch"));

这是一个演示,我正在观察滚动是否超过一个像素,以决定是否将标题设置为固定位置