2015-02-23 51 views
3

我已经忙于单页导航。下面你会发现更多关于问题和我的愿望的信息。单页导航问题 - 更新/突出显示活动状态并滚动到锚点

它应该如何运作?

一旦导航项被点击时,滚动到其特定的部分和更新活动类的菜单。如果页面滚动到特定的部分,它也应该更新活动状态 - 所以将类更改为其特定的锚点。

固定头

的网站我也用一个固定的头,所以这不应该被覆盖的特定部分。因此,当标题底部到达该部分的顶部时,菜单应该停止滚动。

变截面

单页设计的所有截面都有不同的高度。

问题

我已经尝试了很多的代码,得到它的工作。大部分代码正在工作,但这并不是所有浏览器都是一样的。另外我在更新特定部分的活动状态时遇到了一些问题 - 与活动锚点相匹配。

代码

我使用jQuery来创建一个平滑滚动锚泊。 You can see my working code at JSfiddle

这里是所有资源:

JS

这里我CONTROLE导航的点击功能。 所以,当用户点击#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;   
    }); 


}); 

除了点击功能,我也想,当一个页面各处用户滚动,它会自动更新活动语句。

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(); 
}); 

在上面的代码中,我认为,if (target.position().top <= windowPos && target.position().top + target.height() > windowPos)行是不正确的,也许长..

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

+1

此库完全符合你的要求 - http://imakewebthings.com/waypoints/ – 2015-02-27 17:57:55

回答

4

看你的代码,我已经更新了你的下面一个说行:

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

这样,它会得到目标的差异顶端减去头的高度(因为它会始终可见),然后检查窗口的位置。如果它比较差,用户已经通过了这个锚,所以菜单中的对应链接被突出显示。

而且你的第一个环节没有它停泊在小提琴,所以:

<li><a href="#hero" class="current">Home</a></li> 

这些更改后,一切似乎都正常工作。

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

编辑:
要更新哈希,我试图用一个简单的window.location.hash = anchorId;,但它导致了FF和IE一些奇怪的滚动问题。我花了一些时间,但我无法弄清楚会发生什么。

所以,我建议一个我已经使用的技巧,在散列中使用#!。这样一来,你的代码将是这样的:

window.location.hash = '#!' + anchorId.replace('#', ''); 

而在滚动功能,像:

window.location.hash = '#!' + anchorId.attr('href').replace('#', ''); 

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

而且,如果你愿意,你可以检查对于页面加载中的哈希,删除感叹号并将页面滚动到所需的锚点。或者,如果你想避免所有这些,你总是可以使用一些历史插件,如this one。在你的情况下,我个人不会使用这个插件,但如果它值得与否,这是你的呼叫。

希望它有帮助!

+0

谢谢埃弗顿。它运作完美。还有一个问题,有没有办法更新滚动中的URL哈希? – Caspert 2015-02-28 11:57:34

+0

'location.hash.replace(“#”,“”)'你为什么不用这个代码 – 2015-03-01 15:16:25

+0

你可以试试我的更新吗?我无法在小提琴中测试它,但我认为它可以帮助你。 :) – 2015-03-02 12:57:35