单页导航出现问题 - 更新/突出显示活动状态并滚动到锚点

Cas*_*ert 5 html javascript css jquery

我已经忙于一页导航了。您将在下面找到有关问题和我的愿望的更多信息。

它应该如何工作?

单击导航项后,滚动到其特定部分并更新菜单的活动类。如果页面滚动到其特定部分,它也应该更新活动状态 - 因此将类更改为其特定锚点。

固定标题

对于网站,我还使用了固定标题,因此不应覆盖特定部分。因此,当标题底部到达该部分的顶部时,菜单应停止滚动。

可变部分

一页设计上的所有部分都有不同的高度。

问题

我已经尝试了很多代码,以使其工作。大部分代码都可以工作,但并非在所有浏览器中都相同。此外,我在更新特定部分的活动状态时遇到了一些麻烦 - 与活动锚点匹配。

代码

我使用 jQuery 创建了一个平滑的滚动到锚点。你可以在 JSfiddle 看到我的工作代码

以下是所有资源:

JS

这里我控制导航的点击功能。因此,当用户单击 的列表项时#primary-navwrapper,然后更改活动状态类并滚动到与单击的锚点匹配的特定部分。

$('#primary-navwrapper li').find('a[href^="#"]').click(function(event) { 
    // Prevent from default action to intitiate
    event.preventDefault();


    $('#primary-navwrapper li a').removeClass("current");
    $(this).addClass("current");


    // The id of the section we want to go to.
    var anchorId = $(this).attr("href");
    
    // Our scroll target : the top position of the
    // section that has the id referenced by our href.
    var target = $(anchorId).offset().top - offset;
    //console.log(target);
    
    
    $('html, body').animate({ scrollTop: target }, 500, function () {
        //window.location.hash = '!' + id;
        window.location.hash = anchorId;        
    });
    

});
Run Code Online (Sandbox Code Playgroud)

除了点击功能,我还希望当用户滚动一页时,它会自动更新活动语句。

function setActiveListElements(event){
    // Get the offset of the window from the top of page
    var windowPos = $(window).scrollTop();
    
    $('#primary-navwrapper li a[href^="#"]').each(function() { 
        var anchorId = $(this);
        var target = $(anchorId.attr("href"));
        
        if (target.length > 0) {
            if (target.position().top <= windowPos && target.position().top + target.height() > windowPos) {
                $('#primary-navwrapper li a').removeClass("current");
                anchorId.addClass("current");
            }
        }
    });
}

$(window).scroll(function() {
    setActiveListElements();
});
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我认为该行if (target.position().top <= windowPos && target.position().top + target.height() > windowPos)不正确,可能太长了..

如果有任何问题或什么,我想听听你的意见。卡斯帕

Eve*_*ger 6

查看您的代码,我已经更新了您为以下代码所说的行:

if (target.position().top - $('#header').outerHeight() <= windowPos) {
    $('#primary-navwrapper li a').removeClass("current");
    anchorId.addClass("current");
}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,它将获得目标与顶部的差异减去标题的高度(因为它始终可见),然后检查窗口的位置。如果它较差,则用户已通过此锚点,因此菜单中的相应链接会突出显示。

你的第一个链接在小提琴中没有它的锚点,所以:

<li><a href="#hero" class="current">Home</a></li>
Run Code Online (Sandbox Code Playgroud)

进行这些更改后,一切似乎都正常。

JSFiddle:http : //jsfiddle.net/8n06pvy9/17/

编辑:
为了更新哈希,我尝试使用一个 simple window.location.hash = anchorId;,但它导致 FF 和 IE 中出现一些奇怪的滚动问题。我已经花了一些时间,但我无法弄清楚会发生什么。

所以,我建议一个我已经使用过的技巧,#!在哈希中使用。这样,您的代码将是这样的:

window.location.hash = '#!' + anchorId.replace('#', '');
Run Code Online (Sandbox Code Playgroud)

在滚动功能中,像这样:

window.location.hash = '#!' + anchorId.attr('href').replace('#', '');
Run Code Online (Sandbox Code Playgroud)

JSFiddle:http : //jsfiddle.net/8n06pvy9/18/

而且,如果需要,您可以检查页面加载中的哈希值,删除感叹号并将页面滚动到所需的锚点。或者,如果你想避免所有这些,你总是可以使用一些历史插件,比如这个。在您的情况下,我个人不会为此使用插件,但无论是否值得,这是您的电话。

希望能帮助到你!