【问题标题】:jQuery in-page navigation with menu highlighting (optimisation)带有菜单突出显示的 jQuery 页面内导航(优化)
【发布时间】:2017-09-08 17:55:20
【问题描述】:

我目前正在构建一个 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);
    }
}

【问题讨论】:

    标签: jquery optimization scroll navigation


    【解决方案1】:

    在 'highlightNav' 函数中,您最好使用 while 循环,例如因此您可以搜索 $currentSection,获取 $correspondingNavLink,跳出循环,然后删除/添加“活动”类一次。

    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/

    【讨论】:

    • 这确实更优雅,但是现在在不应跟踪的部分内滚动时不会删除突出显示...你有什么办法解决这个问题吗?
    • @Adi 我更新了我的答案:使用新的状态变量,它现在应该可以按要求工作了。
    猜你喜欢
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 2012-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    相关资源
    最近更新 更多