我正在尝试制作一个静态网站,当 div 子元素进入视口(viewport)时(确切地说,当 div 元素进入视口(viewport)的上 50% 时),会将 side-nav 中相应的 div 类更改为“积极的”。它应该可以向下和向上滚动。
到目前为止,我已经尝试了其他线程的几种解决方案,但没有成功。我想我一直在错误地对待这个问题。
$(window).on('scroll', function() {
$("#vars-args").each(function() {
if (elementInViewport2($(this))) {
$(this).find("#div1a").addClass("active");
}
});
});
function elementInViewport2(el) {
var top = el.offsetTop;
var left = el.offsetLeft;
var width = el.offsetWidth;
var height = el.offsetHeight;
while (el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}
return (
top < (window.pageYOffset + window.innerHeight) &&
left < (window.pageXOffset + window.innerWidth) &&
(top + height) > window.pageYOffset &&
(left + width) > window.pageXOffset
);
}
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
<div id="side-nav">
<a href="" id="div1a">1</a>
<a href="" id="div2a">2</a>
<a href="" id="div3a">3</a>
<a href="" id="div4a">4</a>
<a href="" id="div5a">5</a>
<a href="" id="div6a">6</a>
</div>
<div id="content">
<div id="div1">
<!--content-->
</div>
<div id="div2">
<!--content-->
</div>
<div id="div3">
<!--content-->
</div>
<div id="div4">
<!--content-->
</div>
<div id="div5">
<!--content-->
</div>
<div id="div6">
<!--content-->
</div>
</div>
另请注意,内部每个 div 的内容可以大于视口(viewport)的大小。
我在使用 javascript 时遇到了问题。另请注意,当前的 JS 是从其他线程复制的。
最佳答案
这可以使用 IntersectionObserver 来实现,正如@cloned 在评论中所说:https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
要实现此目的,您需要一个作为参数传递的回调函数,该函数在isIntersecting
为true(一个选项)时执行 对象(下面将阈值设置为元素的 50%)和一个 IntersectionObserver。
回调根据条目的 id 将事件类切换到 a 元素。
最后,我们循环遍历 div 并让观察者观察它们。
const callback = (entries, observer) => {
entries.forEach(entry => {
const navItem = document.querySelector('#' + entry.target.id + 'a');
if (entry.isIntersecting) {
console.log(navItem.getAttribute('id'));
navItem.classList.add('active');
} else {
navItem.classList.remove('active');
}
});
};
const options = {
threshold: 0.5
};
const observer = new IntersectionObserver(callback, options);
const container = document.getElementById('content');
const targetElements = container.querySelectorAll('div');
targetElements.forEach(element => {
observer.observe(element);
});
这里有一个JSBin来演示它 https://jsbin.com/riyuhediso/47/edit?html,js,console,output
请注意,虽然它证明了其可行性,但尚未针对可能很重要的性能问题进行分析,因此我不保证它。
如果您使用Bootstrap,您可以使用ScrollSpy lib https://getbootstrap.com/docs/4.1/components/scrollspy/还有很棒的 ScrollMagic http://scrollmagic.io/
关于javascript - 更改滚动到视口(viewport)时的事件状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53168030/