[英]Confused about highlighting active menu item on scroll (Vanilla JS)
我发现此功能可在您滚动到具有相同ID的部分时突出显示活动菜单锚。 我了解大多数代码的工作原理,但我不了解window onscroll事件如何知道如何使用.active类更新正确的定位标记。
所有的JS:
var section = document.querySelectorAll(".section"); var sections = {}; var i = 0; Array.prototype.forEach.call(section, function(e) { sections[e.id] = e.offsetTop; }); window.onscroll = function() { var scrollPosition = document.documentElement.scrollTop || document.body.scrollTop; for (i in sections) { if (sections[i] <= scrollPosition) { document.querySelector('.active').setAttribute('class', ' '); document.querySelector('a[href*=' + i + ']').setAttribute('class', 'active'); } } };
从这支笔: https : //codepen.io/zchee/pen/ogzvZZ
这部分使我感到困惑:
document.querySelector('a[href*=' + i + ']').setAttribute('class', 'active');
我知道setAttribute
将一个活动类添加到锚标记中-但是当滚动时querySelector
如何找到正确的锚来更新?
我尝试从(在数组循环中)记录索引变量[i]
以获取当前节的ID(滚动),但它返回当前滚动位置(以数字表示)。
这就是为什么我不明白为什么此处插入的'i'变量:( ('a[href*=' + i + ']')
代表onscroll事件中相应的段ID的原因。
我想我不太了解此forEach函数的运行方式没有帮助:
Array.prototype.forEach.call(section, function(e) {
sections[e.id] = e.offsetTop;
});
我知道它循环遍历所有部分,并将这些sections[e.id]
推送到空对象sections = {}
,稍后将在onscroll事件中使用它,但是我的理解在那里停止了。 :-/
对不起,我不知道如何更好地表达这个问题。 我已经花了几个小时试图绕过它。 我找不到任何与此类似的主题示例,但是我想在任何地方使用它之前先了解其工作原理。
非常感谢您的反馈! :-)
根据W3学校的文档 , .querySelector
获取文档中的第一个元素,其类等于要搜索的元素。
a[href*=#]
表示querySelector正在查找包含#
所有元素,在您的情况下, 'a[href*=' + i + ']'
进一步指定当前href
为i
元素。
因此,当您将所有内容组合在一起时,代码
for (i in sections) {
if (sections[i] <= scrollPosition) {
document.querySelector('.active').setAttribute('class', ' ');
document.querySelector('a[href*=' + i + ']').setAttribute('class', 'active');
}
}
查找具有等于当前“ i”部分的href的元素,并将该元素的属性类设置为active。
希望能帮助到你!
编辑
每当滚动窗口时,都会发生以下情况:
scrollPosition
变量,该变量设置为等于documentElement的“最高”点(或scrollTop) 或文档正文的“最高”点(或scrollTop) i
:如果该节小于或等于scrollPostition,则它将先前处于活动状态的类更改为null并将当前节的类设置为活动。 然后,对每个部分重复此操作,直到到达当前部分。 因此,从技术上讲,直到当前节为止的每个节在某个时候都处于“活动”状态(因此,每个节名称的控制台日志)。
本质上,如果要从“主页”转到“联系”,它将在“主页”中删除活动类并将其添加到“ Portfolio”,然后将其从“ Portfolio”删除并将其添加到“关于”,然后最后将其从“关于”中删除,并将其添加到“联系人”中。 这样,它似乎可以“知道”您正在执行的部分,但实际上是遍历所有部分,直到到达正确的部分为止。
(另一个示例:如果您从“联系人”转到“投资组合”,则会从“联系人”中删除活动内容并将其添加到“首页”,意识到它仍不在正确的位置,然后从“首页”中删除活动内容并添加将其添加到“投资组合”中。这对于具有多个部分的网站可能无法正常工作,但在中小型网站上似乎是无缝的!)
也许有更好的方法来解释这一点,但我希望这种“视觉”有所帮助!
非常简单。 您看到的代码中,变量部分包含所有带有类“ .section”的div。
var section = document.querySelectorAll(".section");
然后,使用代码根据窗口偏移值,将所有div ID及其滚动位置填充到“ sections”数组中
Array.prototype.forEach.call(section, function(e) { sections[e.id] = e.offsetTop; });
您的section数组在内存中将像这样
sections['home']=position of home sections['portfolio']=position of portfolio sections['about']=position of about sections['contact']=position of contact
因此,当for循环在部分上运行时,它会像这样给出div id
for (i in sections) { * now "i" gives the id of all div one by one }
同时,在此循环中,querySelector将搜索包含特定href文本的锚标记。
*this will give you specific anchor tag like *document.querySelector('a[href*='home']') -> a[href*='home'] -> a[href*='portfolio'] -> a[href*='about'] -> a[href*='contact']
我希望这可以轻松地向您解释。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.