通过JS拦截history.pushState和replaceState事件

作者:小圆点

时间:2026-10-22

浏览:170

本文介绍了如何通过重写history对象的方法,拦截pushState和replaceState调用并触发自定义事件。由于原生onpopstate无法捕获这些操作,该方案通过包装原始函数并手动派发Event对象,实现了在URL变更时执行特定逻辑的功能。

文章目录

问题背景与现状

利用 history.pushState 和 history.replaceState 方法,开发者可以在不刷新页面的前提下修改浏览器地址栏的URL。然而,这种机制导致无法直接通过常规手段获取由 AJAX 加载的新页面内容。

尽管部分 HTML5 文档指出 window.onpopstate 事件可用于拦截 pushState 的调用,但实际测试表明,该事件在此场景下无效,无法成功拦截 pushState 产生的消息。

解决方案来源

经过搜索查找,找到了能够正确获取 pushState 事件的有效代码实现。

https://stackoverflow.com/a/25673911

核心代码实现


// 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('pushState', function(e) {
  console.warn('THEY DID IT AGAIN!');
});
window.addEventListener('replaceState', function(e) {
  console.warn('THEY DID IT AGAIN!');
});

原理说明与注意事项

该代码的核心逻辑是对 history 对象中现有的函数进行重写,并在执行原始逻辑后,手动触发一个自定义事件。

此方法有效解决了 pushState 操作无法激活相应事件的问题。

此外,建议将这段代码放置在文档加载之前执行,以确保其生效。

以上关于通过 JS 拦截 pushState 和 replaceState 事件的分享到此结束,希望能为读者提供参考,并感谢大家的支持。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章