我找到了这个功能,当您滚动到具有相同ID的部分时,它会突出显示活动的菜单锚点。我理解大多数代码是如何工作的,但我不知道窗口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');
}
}
};
&#13;
从此Pen:https://codepen.io/zchee/pen/ogzvZZ
这部分让我困惑:
document.querySelector('a[href*=' + i + ']').setAttribute('class', 'active');
我得到setAttribute
在锚标记中添加了一个活动类 - 但是当滚动时querySelector
如何找到要更新的正确锚?
我尝试从(for for array循环)中记录索引变量[i]
以获取当前节的id(onscroll),但它返回当前滚动位置(作为数字)。
这就是为什么我不明白为什么插入&#39; i&#39;变量here:('a[href*=' + i + ']')
表示onscroll事件中对应的section id。
我想我并不能真正了解这个forEach功能是如何运作的:
Array.prototype.forEach.call(section, function(e) {
sections[e.id] = e.offsetTop;
});
我得到它循环遍历所有部分并将sections[e.id]
推送到稍后在onscroll事件中使用的空对象sections = {}
- 但这是我的理解停止的地方。 : - /
抱歉,我不知道如何更好地表达这个问题。我花了好几个小时试图绕过它。我无法找到与此类似的任何主题示例,但我希望在我在任何地方使用它之前了解它是如何工作的。
非常感谢一些反馈! : - )
答案 0 :(得分:1)
根据W3学校的documentation,.querySelector
获取文档中的第一个元素,其中class等于被搜索的元素。
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');
}
}
查找具有等于当前&#39; i&#39;的href的元素。 section,并将该属性类设置为该元素的活动状态。
希望它有所帮助!
修改强>
每当滚动窗口时,都会发生以下情况:
scrollPosition
的变量,该变量设置为等于
documentElement&#34; s&#34;最高&#34; point(或scrollTop) OR
文件机构&#34;最高&#34; point(或scrollTop)i
:
如果该部分小于或等于scrollPostition,它会将先前活动的类更改为null,并将当前部分的类设置为活动状态。然后对每个部分重复,直到它到达当前部分。所以从技术上讲,每个部分都取决于当前部分的制作和活动的#34;在某些时候(因此每个部分名称的控制台日志)。
基本上,如果你要从&#34; Home&#34;到&#34;联系&#34;,它会删除&#34; Home&#34;并将其添加到&#34;投资组合&#34;,然后将其从&#34;投资组合&#34;并将其添加到&#34;关于&#34;,最后将其从&#34;关于&#34;并将其添加到&#34;联系&#34;。这样它似乎“知道”。你在哪个部分,但它实际上经历了所有部分,直到它到达正确的部分。
(另一个例子:如果您从&#34;联系&#34;到&#34;投资组合&#34;,它将从&#34;联系&#34;中删除活动,并将其添加到&#34; Home&#34;,意识到它仍然没有在正确的那个,然后从&#34; Home&#34;中删除活动并将其添加到&#34; Portfolio&#34;。这可能不会也适用于有大量部分的网站,但在中小型网站上看起来无缝!)
可能有更好的方法来解释这个问题,但我希望这可以通过视觉方式解决这个问题。帮助!
答案 1 :(得分:1)
非常简单。 当你看到代码
时,你的变量部分包含所有带有“.section”类的divvar section = document.querySelectorAll(".section");
然后你的“sections”数组使用代码
根据窗口偏移值填充所有div id及其滚动位置Array.prototype.forEach.call(section, function(e) { sections[e.id] = e.offsetTop; });
你的sections数组在内存中会是这样的
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']
我希望这会很容易解释你。