带菜单突出显示的jQuery页面导航(优化)

时间:2017-09-07 10:19:16

标签: jquery optimization scroll navigation

我目前正在构建一个jQuery插件,它会根据滚动位置是否在匹配部分内来突出显示某些导航链接。

我现在运行它的方式是有效的,它正在做我想做的一切。请参阅小提琴Demo Fiddle

当我在相应部分内时,链接会正确突出显示。另外,当我在一个区域之外时,我想删除突出显示。

我在这里这样做:

if (scrollPos + settings.offset >= currentSectionTop && scrollPos + settings.offset < currentSectionBottom) {
    // Get the section ID and corresponding nav link.
    var currentSectionID = $currentSection.attr('id'),
        $correspondingNavLink = sectionMap[currentSectionID];

    // If the link isn't active already, make it so.
    if (!$correspondingNavLink.hasClass('active')) {
        $navLinks.removeClass('active');
        $correspondingNavLink.addClass('active');
        console.log('added active class');
    }

    // Because this is the correct section, exit.
        return false;
} else {
    if ($navLinks.hasClass('active')) {
        $navLinks.removeClass('active');
        console.log('removed active class');
    }                            
}

当我在第二部分内滚动并向下滚动时出现问题。在这种情况下,活动类会不断添加和删除(检查控制台日志),这正是我想要阻止的。

当我在第一部分内部滚动时没有发生这种情况,因为这是在每个循环中检查的第一部分,因为它匹配,我们退出循环。

所以,即使结果正是我想要的,我仍然希望通过删除remove-add-remove-add ...循环来进行这种小优化。

关于我如何做到这一点的任何想法?

非常感谢!

更新

在跟进JeyPack的回答之后,我得到了我需要的东西。要在节之外滚动时删除活动类,我使用的变量只有在找到节时才会变为true。在while循环之后,如果该变量仍为false,则意味着我们在任何部分之外滚动,因此如果应用了活动类,我们将其删除。

感谢JeyPack指出我正确的方向和优化。

这是更新后的代码:

function highlightNav() {
    // Get the current scroll position.
    var currentSectionID, $correspondingNavLink, $currentSection, currentSectionTop, currentSectionBottom,
        scrollPos = $w.scrollTop() + settings.offset,
        i = $sections.length,
        found = false;

    // Loop through each section.
    while (--i >= 0) {
        // get current section
        $currentSection = $sections.eq(i);
        currentSectionTop = $currentSection.offset().top;
        currentSectionBottom = $currentSection.offset().top + $currentSection.outerHeight(true);

        // If we scrolled inside the section...
        if (scrollPos >= currentSectionTop && scrollPos < currentSectionBottom) {
            // Get the section ID and corresponding nav link.
            currentSectionID = $currentSection.attr('id');
            $correspondingNavLink = sectionMap[currentSectionID];

            found = true;
            // Because this is the correct section, break.
            break;
        }
    }

    if (!found && $navLinks.hasClass('active')) {
        $navLinks.removeClass('active');
    }

    // If the link isn't active already, make it so.
    if ($correspondingNavLink && !$correspondingNavLink.hasClass('active')) {
        $navLinks.removeClass('active');
        $correspondingNavLink.addClass('active');
        window.console.log('added active class', $correspondingNavLink);
    }
}

1 个答案:

答案 0 :(得分:0)

在'highlightNav'功能中你最好使用while循环,例如所以你可以搜索$ currentSection,获取$ associatedNavLink,然后跳出循环并在之后删除/添加'active'类。

function highlightNav() {
    // Get the current scroll position.
    var currentSectionID, $currentSection, currentSectionTop, currentSectionBottom,
        $correspondingNavLink = null,
        scrollPos = $w.scrollTop() + settings.offset,
        i = $sections.length;

    // Loop through each section.
    while (--i >= 0) {
        // get current section
        $currentSection = $sections.eq(i);
        currentSectionTop = $currentSection.offset().top;
        currentSectionBottom = $currentSection.offset().top + $currentSection.outerHeight(true);

        // If we scrolled inside the section...
        if (scrollPos >= currentSectionTop && scrollPos < currentSectionBottom) {
            // Get the section ID and corresponding nav link.
            currentSectionID = $currentSection.attr('id');
            $correspondingNavLink = sectionMap[currentSectionID];
            // Because this is the correct section, break.
            state = 1;
            break;
        }
    }

    // If the link isn't active already, make it so.
    if (state === 1) {
        state = 0;
        if (!$correspondingNavLink.hasClass('active')) {
            $navLinks.removeClass('active');
            $correspondingNavLink.addClass('active');
            window.console.log('added active class', $correspondingNavLink);
        }
    } else if (state !== 2) {
        state = 2;
        $navLinks.removeClass('active');
        window.console.log('remove active class');
    }
}

我编辑了你的小提琴:https://jsfiddle.net/cwfqmv50/2/