1、监听浏览器 url 的变化
// 监听 hash 值的变化
window.onhashchange = function () {
console.log('hashchange 触发!');
}
// 监听 url 的变化
// 1、触发事件:history.back、history.forward、history.go 三种事件
// 2、非触发事件:history.pushState、history.replaceState (通过手动拦截触发)
window.onpopstate = function () {
console.log('popstate 触发!');
}
// 使用 addEventListener 监听 url 和 hash 的变化
// 1、使用 addEventListener 进行事件监听( 同时添加多个事件 )
// 2、最好不使用 window.onhashchange 多个会覆盖
// 3、监听 hash 值的变化( go、back、forward... )
// 4、监听 popstate 的时候,此时路由已经完成的导航(只能做善后的工作)
window.addEventListener('hashchange' || 'popstate', function() {
// ...
console.log('监听到url 或 hash 值的变化');
// ...
}, false);
2、Histroy:历史记录前进与后退
window.history.back() // 后退一步
window.history.go(-1) // 后退一步
window.history.forward() // 前进一步
window.history.go(1) // 前进一步
window.history.go(n) // 前进n步
3、Histroy:添加和修改历史记录中的条目
// 1、stateObject:javascript对象
// 2、title:标题
// 3、URL:新历史记录条目的 URL 由此参数指定
// 4、不会触发 popstate、hashchange 事件
history.pushState(stateObject,title,URL);
history.replaceState(stateObject,title,URL);
4、onpopstate 监听 history.pushState、history.replaceState 变化
<body>
<div>
<button id='pushState'>pushState </button>
<button id='replaceState'>replaceState </button>
<button id='forward'>forward </button>
<button id='back'>back </button>
<button id='go'>go </button>
</div>
</body>
<script src="./index.js"></script>
<script>
const btnPush = document.getElementById('pushState');
const btnReplace = document.getElementById('replaceState');
const btnForward = document.getElementById('forward');
const btnBack = document.getElementById('back');
const btnGo = document.getElementById('go');
// 手动触发 pushState 事件
btnPush.addEventListener('click', () => {
history.pushState(null, null, '/aaa');
}, true);
// 手动触发 replaceState 事件
btnReplace.addEventListener('click', () => {
history.replaceState(null, null, '/bbb');
}, true);
// 手动触发 forward 事件
btnForward.addEventListener('click', () => {
history.forward()
}, true);
// 手动触发 back 事件
btnBack.addEventListener('click', () => {
history.back();
}, true);
// 手动触发 go 事件
btnGo.addEventListener('click', () => {
history.go(-1);
}, true);
</script>
index.js
// 更改路由后去 挂载、更新子应用
function urlReroute(type) {
return ()=>{
console.log('触发事件',type);
}
}
// 通过拦截监听 back、forward、go、popstate、replaceState 事件
window.addEventListener("popstate", urlReroute('pop'));
// 赋值自定义函数
window.history.pushState = patchedUpdateState(
window.history.pushState,
"pushState"
);
window.history.replaceState = patchedUpdateState(
window.history.replaceState,
"replaceState"
);
// 拦截 pushState 和 replaceState
function patchedUpdateState(updateState, methodName) {
return function () {
// 更新前的 url
const urlBefore = window.location.href;
// 执行 pushState 或者 replaceState 并返回结果
const result = updateState.apply(this, arguments);
// 更新后的 url
const urlAfter = window.location.href;
if(urlBefore != urlAfter){
window.dispatchEvent(
createPopStateEvent(window.history.state, methodName)
);
}
};
}
// 使用 PopStateEvent 创建 popstate 事件对象
function createPopStateEvent(state, originalMethodName) {
let evt;
try {
evt = new PopStateEvent("popstate", { state });
} catch (err) {
// IE 11
evt = document.createEvent("PopStateEvent");
evt.initPopStateEvent("popstate", false, false, state);
}
evt.singleSpa = true;
evt.singleSpaTrigger = originalMethodName;
return evt;
}