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

you*_*t13 5 javascript firefox jquery

我正在尝试实现一个小代码,当我点击锚点(动画后出现锚点名称)时,我可以使用它平滑滚动,如果我按下浏览器的后退按钮,我想返回到页面顶部并更新 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 }, '');
  }
});
Run Code Online (Sandbox Code Playgroud)

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

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

$('html').animate
Run Code Online (Sandbox Code Playgroud)

或者 $('body').animate

但行为是一样的。

如果有人能明白为什么它不起作用。

谢谢

Ser*_*nko 1

您正在触发此行中的其他历史记录更改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);
    });
Run Code Online (Sandbox Code Playgroud)

另外,它似乎$('html,body').animate运行回调两次,因此扰乱了历史记录。这就是为什么我只留下html。

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

if (state) {
  $('html,body').animate({ scrollTop: 0 }, 300)
Run Code Online (Sandbox Code Playgroud)