【问题标题】:How to detect when history.pushState and history.replaceState are used? [duplicate]如何检测何时使用 history.pushState 和 history.replaceState? [复制]
【发布时间】:2011-07-05 00:04:36
【问题描述】:

当历史状态被修改时,我可以订阅一些事件吗?怎么样?

【问题讨论】:

    标签: javascript html browser-history pushstate


    【解决方案1】:

    当历史改变时应该触发 onpopstate 事件,你可以像这样在你的代码中绑定它:

    window.onpopstate = function (event) {
      // do stuff here
    }
    

    该事件也可能在页面加载时触发,您可以确定该事件是否从页面加载触发,或者通过检查事件对象的状态属性使用pushState/replaceState,如果事件将未定义是由页面加载引起的

    window.onpopstate = function (event) {
      if (event.state) {
        // history changed because of pushState/replaceState
      } else {
        // history changed because of a page load
      }
    }
    

    不幸的是,目前没有 onpushstate 事件,要解决这个问题,您需要包装 pushState 和 replaceState 方法来实现您自己的 onpushstate 事件。

    我有一个库,可以更轻松地使用 pushState,它可能值得一试,名为 Davis.js,它提供了一个简单的 api,用于处理基于 pushState 的路由。

    【讨论】:

    • 似乎 event.state 可能仍会在页面加载时设置(Chrome)。
    • Mozilla/Firefox 在页面加载时不会发出 onpopstate 事件,但 Safari/Chrome 会
    • 在我的例子中,这个事件发生在 ajax 调用成功之后。可能由于这个原因,我无法第一次检测到该事件。如果我单击后退/前进按钮,那么效果很好,但是我不希望我的用户单击这些历史按钮。
    • docs 明确声明 pushState 不会触发 onpopstate
    • 这个答案不正确。根据文档,在 history.back()、history.forward()、history.go() 的情况下会触发 onpopstate。这是公认的答案。
    【解决方案2】:

    我曾经使用它来通知何时调用 pushStatereplaceState

    // Add this:
    var _wr = function(type) {
        var orig = history[type];
        return function() {
            var rv = orig.apply(this, arguments);
            var e = new Event(type);
            e.arguments = arguments;
            window.dispatchEvent(e);
            return rv;
        };
    };
    history.pushState = _wr('pushState'), history.replaceState = _wr('replaceState');
    
    // Use it like this:
    window.addEventListener('replaceState', function(e) {
        console.warn('THEY DID IT AGAIN!');
    });
    

    不过,这通常是矫枉过正。它可能不适用于所有浏览器。 (我只关心我的浏览器版本。)

    注意。它也不适用于 Google Chrome 扩展内容脚本,因为它不允许更改站点的 JS 环境。您可以通过插入带有上述代码的<script> 来解决这个问题,但这更加矫枉过正。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-10
      • 2014-02-17
      • 2013-12-04
      • 1970-01-01
      • 2016-10-18
      • 1970-01-01
      • 1970-01-01
      • 2020-12-18
      相关资源
      最近更新 更多