如何将活动类添加到正确的导航项内部滚动我的事件?

时间:2017-07-04 10:04:16

标签: javascript

所以我有一个页面,当你滚动到相应的部分时,活动菜单项会突出显示。

我的代码有效,但我不明白为什么,特别是这一部分:

document.querySelector('nav a[href="' + anchorID + '"]').classList.add("active");

  1. 在window.onscroll上,for循环从菜单中收集所有锚点(nav a

  2. 然后我可以访问单个的anchorID(hrefs):

  3. 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? )

    我对此感到很困惑,我敢打赌这是愚蠢的,我忽略了!

    非常感谢一些输入! : - )

1 个答案:

答案 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; ......等等一个