当达到 50% 视口高度时,使用 IntersectionObserver 和 rootMargin 进行更改

mrw*_*web 5 intersection-observer

我完全被交叉点观察者的rootMargin属性弄糊涂了。

我的目标是在元素的一半高度穿过视口的垂直中心时向元素添加一个类。

期望结果图

在我当前的项目中,我所做的一切似乎都不会影响“根交叉矩形”,并且总是立即添加该类。我已经在最新的 Chrome 和 Firefox 中进行了测试。

这是简化的测试用例:

// https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

const options = {
  root: null, // default, use viewport
  rootMargin: '0px 0px -50% 0px',
  threshold: 0.5 // half of item height
}

const circle = document.getElementById('circle');

const observerCallback = function(entries, observer) {
  console.log('intersected');
  circle.classList.add('intersected');
}

window.addEventListener('load', function(event) {

  const observer = new IntersectionObserver(observerCallback, options);

  observer.observe(circle);

}, false);
Run Code Online (Sandbox Code Playgroud)
.circle {
  margin: 100vh auto;
  width: 200px;
  height: 200px;
  background-color: tomato;
  border-radius: 50%;
  transition: background-color 2s ease-in-out;
}

.circle.intersected {
  background-color: mediumseagreen;
}
Run Code Online (Sandbox Code Playgroud)
<div class="circle" id="circle"></div>
Run Code Online (Sandbox Code Playgroud)

Kno*_*ert 6

有时我自己也很困惑 IntersectionObserver,但参考这篇文章,对我来说更容易掌握。

什么可能是给你的麻烦是检查,如果它实际上是相交与否。所以我在属性中添加了一个 if 语句isIntersecting在 IntersectionObserver 条目上找到。

我还添加了对 IntersectionObserver 的检查,如果它在客户端上可用并root: null从选项中删除,因为它应该默认为视口。

如果您只使用此 IntersectionObserver 添加类一次,请不要忘记observer.unobserve(circle)observer.disconnect()在不再需要时使用以防止内存泄漏。

// https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

const options = {
  rootMargin: '0px 0px -50% 0px',
  threshold: 0.5 // half of item height
}

const circle = document.getElementById('circle');

const observer = new IntersectionObserver(entries => {
  const [{ isIntersecting }] = entries
  if (isIntersecting) {
    console.log('intersected');
    circle.classList.add('intersected');
  } else {
    console.log('not-intersecting');
  }
}, options);

window.addEventListener('load', () => {
  if ('IntersectionObserver' in window) observer.observe(circle);
}, false);
Run Code Online (Sandbox Code Playgroud)
.circle {
  margin: 100vh auto;
  width: 200px;
  height: 200px;
  background-color: tomato;
  border-radius: 50%;
  transition: background-color 2s ease-in-out;
}

.circle.intersected {
  background-color: mediumseagreen;
}
Run Code Online (Sandbox Code Playgroud)
<div class="circle" id="circle"></div>
Run Code Online (Sandbox Code Playgroud)