浏览器原生只实现了 onpopstate 的监听,意思只有当浏览器的前进后退,或者时间编程的方式 history.go(),history.back(),history.forward() 才会触发 popstate事件,而history.pushState, history.replaceState 没有事件触发。现在我们来重写这两个方法 让他们能触发对应的事件。
function bindHistoryEvent(method) {
const originMethod = history[method];
if (!originMethod) {
throw new Error("history has not this method named " + method);
}
// 闭包处理
return function () {
let result = null;
try {
originMethod.apply(this, arguments);
//这里也可以把事件名称写死,后面做对应的监听即可
const evt = new Event(method);
evt.arguments = arguments;
//分发事件
window.dispatchEvent(evt);
originMethod.apply(this, arguments);
} catch (error) {
throw new Error("执行出错");
}
return result;
};
}
function init() {
history.pushState = bindHistoryEvent("pushState");
history.replaceState = bindHistoryEvent("replaceState");
}
function test() {
init();
window.addEventListener("pushState", function (e) {
console.log("pushState触发", e);
});
window.addEventListener("replaceState", function (e) {
console.log("replaceState触发", e);
});
history.pushState({ name: "pushState" }, "", "pageA");
history.replaceState({ name: "replaceState" }, "", "pageB");
history.back();
}
test();
看完点赞