45

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

4

2 回答 2

39

我曾经使用它来通知何时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>带有所述代码的 a 来解决此问题,但这更加矫枉过正。

于 2014-09-04T19:52:01.813 回答
10

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 的路由。

于 2011-02-27T17:35:47.360 回答