所以我有一个页面,当你滚动到相应的部分时,活动菜单项会突出显示。
我的代码有效,但我不明白为什么,特别是这一部分:
document.querySelector('nav a[href="' + anchorID + '"]').classList.add("active");
在window.onscroll上,for循环从菜单中收集所有锚点(nav a
)
然后我可以访问单个的anchorID(hrefs):
var anchorID = anchorsArray[i].getAttribute("href");
我不明白的是,.active
类如何根据视口内的当前部分添加到正确的anchorID中 - 当部分id和相应的锚点href之间没有进行比较时。例如。 href& section id:
<a href="#section-2" class="">Section 2</a>
<section id="section-2"></section>
..永远不会在滚动上进行比较。
DEMO:https://jsfiddle.net/zgpzrvns/
所有JS
(function() {
var anchorsArray = document.querySelectorAll("nav a");
var sections = document.querySelectorAll("section");
var sectionsArray = [];
// Collect all sections and push to sectionsArray
for (var i = 0; i < sections.length; i++) {
var section = sections[i];
sectionsArray.push(section);
}
window.onscroll = function() {
var scrollPosition = window.pageYOffset;
for (var i = 0; i < anchorsArray.length; i++) {
// Get hrefs from each anchor
var anchorID = anchorsArray[i].getAttribute("href");
var sectionHeight = sectionsArray[i].offsetHeight;
var sectionTop = sectionsArray[i].offsetTop;
if (
scrollPosition >= sectionTop &&
scrollPosition < sectionTop + sectionHeight
) {
/**
* I don't understand how querySelector finds & adds the active
* class to the correct anchor, when no comparison is made between the
* section ID (that is inside current section in viewport) and the
* anchors ID from anchorsArray
*/
document
.querySelector('nav a[href="' + anchorID + '"]')
.classList.add("active");
} else {
document
.querySelector('nav a[href="' + anchorID + '"]')
.classList.remove("active");
}
}
};
})();
总结:如果滚动视口内的相应部分ID(在滚动事件中从未检测到部分ID时),active
类如何添加到正确的锚ID? )
我对此感到很困惑,我敢打赌这是愚蠢的,我忽略了!
非常感谢一些输入! : - )
答案 0 :(得分:1)
简而言之: 它不需要比较任何ID,因为在滚动时,您将遍历导航中的所有锚点。对于每个检查,如果同一索引处的部分位于视口中。如果是,则添加活动类。
如果您切换导航项的位置,您会看到它会将活动类添加到错误的项目中,因为它只是检查索引。
如果您需要更多解释,请告诉我。然后去编辑答案。
编辑索引说明:
您的导航锚点在数组中,也包含您的部分。
var anchorsArray = document.querySelectorAll("nav a");
var sections = document.querySelectorAll("section");
您正在循环锚点数组
for (var i = 0; i < anchorsArray.length; i++) {
然后你得到你的部分的高度和顶部位置与锚点(变量i)相同的索引
var sectionHeight = sectionsArray[i].offsetHeight;
var sectionTop = sectionsArray[i].offsetTop;
if (
scrollPosition >= sectionTop &&
scrollPosition < sectionTop + sectionHeight
) {
然后将活动类设置为true,或者将其删除(如果为false)。
因此,在每个滚动条上,您的代码执行以下操作:
获得主播 - >检查第一部分是否在范围内 - &gt;如果是 - >添加有效 - &gt;否则删除活动
获得主播2 - &gt;检查第二部分是否在范围内 - &gt;如果是 - >添加有效 - &gt;否则删除活动
获得主播三 - &gt; ......等等一个