2

我想创建一个包含所有子页面的多个(html5)部分的单页网站。有固定的导航。这里有几个要求:

  • 单击导航链接时(例如#home,#about-me),我希望它平滑滚动到该部分
  • 我想在 URL 中使用哈希,例如 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插件非常适合这一切?我将如何实现这一点?该文档没有完全考虑我的要求。

4

1 回答 1

2

动画完成后,您可以手动使用 set location.hash 更改 url。首先,您将使用 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

于 2012-11-15T22:31:17.240 回答