首页 > 解决方案 > Intersection Observer - 突出显示当前部分

问题描述

每当一个部分部分可见或部分不可见时,我都会尝试激活和停用导航栏项目的类。如果我完全向下或向上滚动页面,代码可以正常工作。问题是如果我在一个部分的中间改变方向。

似乎该部分需要首先 100% 不在视野范围内,然后才能重新进入视野才能激活或停用课程(我相信会发生这种情况,因为我们正在检查是否entry.isIntersecting为真,并且首先需要将其更改为错误的)。尽管如此,这会导致不希望的行为。

我试过摆弄 if 语句来检查entry.intersectionRatio,但我似乎也无法让它工作。为了以防万一,我也尝试过不同的浏览器,但行为仍然相同。

我该如何解决这个问题?

这是一些显示这种“错误”行为的代码。它看起来像这样:

const sections = document.querySelectorAll('div.screen');
const config = {
  rootMargin: '-50px 0px -55%'
};

let observer = new IntersectionObserver(function (entries, self) {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      intersectionHandler(entry); 
    }
  });
}, config);

sections.forEach(section => {
  observer.observe(section);
});

function intersectionHandler(entry) {
  const id = entry.target.id;
  const currentlyActive = document.querySelector('nav li.active');
  const shouldBeActive = document.querySelector('nav li[data-ref=' + id + ']');

  if (currentlyActive) {
    currentlyActive.classList.remove('active');
  }
  if (shouldBeActive) {
    shouldBeActive.classList.add('active');
  }
}

代码笔来自这篇文章。

提前致谢。

标签: navbarviewporthighlightsectionsintersection-observer

解决方案


我一直在使用您的 CodePen 并找到了解决问题的方法。

主要思想是确保同时只能有一个元素root。要实现这一点,您需要做两件事:

首先,rootMargin高度应尽可能薄。

rootMargin: '-45% 0px -55%'

第二件事是为您的.screenCSS 类添加边距。

  margin-top: 3px;

(1 或 2 px 可能太小)

该代码在 Firefox 和 Chrome 上运行良好,但在似乎没有实现 InstersectionObserver API 的 Safari 上不起作用。我没有 Windows,所以无法测试 Edge 和 IE。


推荐阅读