如何检测何时使用history.pushState和history.replaceState?

时间:2011-02-26 20:00:19

标签: javascript html5 browser-history pushstate

修改历史状态时是否可以订阅某些事件?怎么样?

2 个答案:

答案 0 :(得分:27)

当历史记录发生变化时,应触发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的路由。

答案 1 :(得分:16)

我曾经使用过这个来通知调用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!');
});
但是,它通常是矫枉过正的。它可能不适用于所有浏览器。 (我只关心我的浏览器版本。)

NB。它也不适用于Google Chrome扩展内容脚本,因为它不允许改变网站的JS环境。您可以通过插入带有所述代码的<script>来解决这个问题,但这样做会更加过分。