在Firefox上使用popState平滑滚动和返回按钮 – 需要单击两次

我正在尝试实现一个小代码,当我点击锚点时我可以顺利滚动(动画后出现锚点名称),如果我按下浏览器的后退按钮,我想返回到页面顶部并更新URL(不带#anchor名称)。

这是代码:

$(function() { // Smooth scrolling when clicking on anchor $('a[href*=#]:not([href=#])').click(function(event) { event.preventDefault(); if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) { var target = $(this.hash); target = target.length ? target : $('[name=' + this.hash.slice(1) +']'); if (target.length) { var hash = this.hash; $('html,body').animate({ scrollTop: target.offset().top - 55}, 300, function() { location.hash = hash; href = window.location.href; history.pushState({page:href}, null, href); }); return false; } } }); // Get smooth scrolling to the top whith back button of browser $(window).bind('popstate', function(event) { var state = event.originalEvent.state; var target = window.location.href.split('#'); var href = target[0]; if (state) { $('html,body').animate({ scrollTop: 0 }, 300, function() { window.location.href = href; }) } }); // First page loading window.onload = function() { history.replaceState({ path: window.location.href }, ''); } }); 

所有上述function在Safari和Chrome下都能正常运行。 但这不是Firefox的情况:一旦执行了平滑向下滚动,我需要在后退按钮上单击两次以重定向到页面顶部。

我在stackoverflow上看到了另一个问题 ,尝试使用和不使用event.preventDefault,也只使用:

 $('html').animate 

$('body').animate

但行为是一样的。

如果有人能够理解为什么它不起作用。

谢谢

您正在此行location.hash = hash;中触发其他历史记录更改location.hash = hash;

所以,我对你的代码进行了一些更改,现在它在我的FF中工作。

在点击处理程序中

  $('html').animate({ scrollTop: target.offset().top - 55}, 300, function() { href = window.location.href; history.pushState({page:href}, null, href.split('#')[0]+hash); }); 

此外,它似乎是$('html,body').animate运行两次回调,因此弄乱了历史。 这就是我只留下HTML的原因。

在popstate处理程序中,我删除了页面重新加载,但如果您愿意,可以保留它:

 if (state) { $('html,body').animate({ scrollTop: 0 }, 300)