达到50%的视口高度时,将IntersectionObserver与rootMargin配合使用

时间:2019-07-03 22:38:20

标签: intersection-observer

我完全被交叉观察者的rootMargin property所迷惑。

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

diagram of desired result

在我当前的项目中,我所做的一切似乎都不会影响“根交叉矩形”,并且总是立即添加该类。我已经在最新的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);
.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;
}
<div class="circle" id="circle"></div>

1 个答案:

答案 0 :(得分:1)

有时候我自己对IntersectionObserver感到非常困惑,但是提到this post,对我来说要容易得多。

可能给您带来麻烦的是检查是否是否真的相交。因此,我添加了一个if语句以及在IntersectionObserver条目中找到的属性QuickMaths

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

如果仅使用此IntersectionObserver一次添加一个类,请不要忘记在不再需要它来防止内存泄漏时使用root: nullobserver.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);
.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;
}