我正在尝试激活和停用导航栏项的类,只要某个部分处于部分视图或部分视图之外。如果我完全向下或向上滚动页面,代码工作正常。问题是如果我在一个部分的中间改变方向。
似乎该部分首先需要100%不可见,然后再回到视图中以便激活或停用类(我相信这是因为我们正在检查entry.isIntersecting
是否为真并且首先需要更改为假)。但是,这会导致不必要的行为。
我试着摆弄if语句来检查entry.intersectionRatio
,但我似乎无法让它工作。我也尝试过不同的浏览器,以防万一,但行为仍然是一样的。
我怎么来这个?
这里有一些code显示这种“马车”行为。它看起来像这样:
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');
}
}
codepen来自this文章。
提前致谢。
我一直在玩你的CodePen,并找到了解决问题的方法。
主要思想是确保同时只有一个元素可以在root
中。要实现这一目标,您需要做两件事:
首先,rootMargin
高度应尽可能薄。
rootMargin: '-45% 0px -55%'
我不确定这是否有效......更正确的方法是:
var vh = document.documentElement.clientHeight;
var topMargin = Math.ceil(-0.45*vh);
var botMargin = Math.ceil(-0.55*vh);
...
rootMargin: topMargin + "px 0px " + botMargin + "px";
第二件事是为你的.screen
CSS类增加一个余量。
margin-top: 3px;
(1或2像素可能太小)
代码在Firefox和Chrome上运行良好,但在似乎没有实现InstersectionObserver API的Safari上无效。我没有Windows所以我无法测试Edge和IE。