jQuery单页网站滚动/哈希问题

时间:2012-11-15 22:26:11

标签: jquery hash scroll

我想创建一个包含所有子页面的多个(html5)部分的1页网站。有一个固定的导航。以下是一些要求:

  • 点击导航链接时(例如#home,#about-me)我希望它能够顺利滚动到该部分
  • 我想在网址中使用哈希,例如domain.com/#about-me
  • 我希望用户能够使用浏览器中的后退/前进按钮,并在使用时顺利滚动到该部分
  • 当直接加载网址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插件对这一切都很有用吗?我该如何实现?文档并不完全考虑我的要求。

1 个答案:

答案 0 :(得分: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哈希中使用它的方式在使用nav转到部分之外不起作用。如果页面上有其他哈希值,并且您希望滚动也适用于它们,则可以删除特定于部分的代码。

此外,它仅适用于支持onhashchange事件的浏览器.http://caniuse.com/hashchange