2012-11-15 19 views
2

我想创建一个包含所有子页面的多个(html5)部分的1页网站。有一个固定的导航。这里有几个要求:jQuery单页网页滚动/散列问题

  • 当点击导航链接(如#home,#约-ME),我希望它平稳地滚动到部分
  • 我想在URL中使用哈希like domain.com/#about-me
  • 我希望用户能够使用浏览器的后退/前进按钮,并在使用时顺利滚动到该部分
  • 当URL domain.com/#about -me被直接加载,我希望它能够平滑地滚动到顶部的#about-me部分。

我一直想弄明白这几天。我试图从零开始,并使用诸如BBQ插件等大量不同的插件。我无法弄清楚。但是我学到了一点,所以我决定从头开始。我更喜欢自己写插件,因为它很轻便。不过,如果使用插件的话,如果自己编写它太麻烦,我一点问题都没有。

现在我有这样的HTML,一个简单的导航:

<nav> 
    <ul> 
     <li><a href="#home">Home</a></li> 
     <li><a href="#about-me">About me</a></li> 
     <li><a href="#portfolio">Portfolio</a></li> 
     <li><a href="#contact">Contact</a></li> 
    </ul> 
</nav> 

和部分:

<div id="content-wrapper"> 
    <section id="home"> 
     <div>content...</div> 
    </section> 
    <section id="about-me"> 
     <div>content...</div> 
    </section> 
    etc... 
</div> 

现在的jQuery的一部分:

// Function to check if section exists 
function isSection(section){ 
    if($('section'+section).length > 0){ 
     return true; 
    } 
    else{ 
     return false; 
    } 
} 

// Scroll function 
function scrollToSection(section){ 
    var offset = $(section).offset().top; 
    $('html, body').stop().animate({ 
     scrollTop: offset 
    }, 600); 
} 

// The Click() function 
$('nav ul a').click(function(){ 
    var section = $(this).attr('href'); 
    if(isSection(section)){ 
     scrollToSection(section); 
    } 
}) 

马上我遇到一个问题。哈希值会改变,但它会立即跳转到该部分,然后一秒钟后它会执行滚动动画(从它的上一个起始位置开始)。我可以使用preventDefault()(这会导致一个完美的平滑动画),但散列不会改变。很好,它改变散列以便浏览器历史记录工作,但当历史按钮被按下时不会发生滚动。

我该如何从这里开始考虑最高要求?任何建议和最好的例子?

我听说BBQ hashchange插件对所有这些工作都很好吗?我将如何实现这一点?文档不完全考虑我的要求。

回答

2

动画完成后,您可以手动使用set location.hash更改网址。首先,你可以使用preventDefault让它动画。在它滚动到你想去的地方后,你可以使用位置。

// Scroll function 
function scrollToSection(section){ 
    var offset = $(section).offset().top; 
    $('html, body').stop().animate({ 
     scrollTop: offset 
    }, 600, function(){ 
     window.location.hash = section; 
    }); 
} 

// The Click() function 
$('nav ul a').click(function(event){ 
    event.preventDefault(); 
    var section = $(this).attr('href'); 
    if(isSection(section)){ 
     scrollToSection(section); 
    } 
    return false; 
})​ 

http://jsfiddle.net/adamzr/p5L57/

另一种方法是让链接改变哈希,他们通常做的。但是,我们可以使用onhashchange事件来在哈希更改时进行滚动。

请以你的点击处理程序:

function locationHashChanged(event) { 
    event.preventDefault(); 
    var section = location.hash; 
    if(isSection(section)){ 
     scrollToSection(section); 
    } 
} 

window.onhashchange = locationHashChanged; 

http://jsfiddle.net/adamzr/XDWuS

这种方法比较好,但我用它在的jsfiddle哈希值的方式将不使用导航去的部分之外的工作。如果你在页面上有其他的哈希值,并且你想要滚动它们,你可以删除特定的代码。

而且,它只会在支持onhashchange event.http浏览器中工作://caniuse.com/hashchange

+0

很好的建议。但是这会导致同样的问题。它立即跳转到该部分,然后一秒钟之后它就会执行滚动动画。 – Bob

+0

@Bob我认为我通过仅在动画完成时更改哈希来解决该问题。 – Adam

+0

啊,是的,谢谢你的例子!我没有做错误的回报,我认为这是造成奇怪的跳跃问题。我认为preventDefault()会照顾到这一点。但是那部分是被覆盖的!谢谢!要求3和4对我来说仍然是一个谜。 – Bob