window.history API 实现禁止浏览器回退到上一页
1. 完整代码
<div class="about-container">
this is about page
<p id="back-count"></p>
<button id="back">back</button>
<button id="forward">forward</button>
</div>
<script>
window.onload = function () {
console.log('页面加载');
// 初始化
const regex = /\/\w+\./;
const pageName = window.location.pathname.match(regex).pop().replace(/\/|\./g, '');
const backCount = document.getElementById('back-count');
let count = window.history.state && window.history.state.count || 0;
document.title = `${pageName} page ${count}`;
backCount.innerHTML = count;
/*
这里一定要先在浏览器历史记录中添加一个新的记录,
因为点击回退按钮后,当前文档会回到上一个 history 记录页面
如果这里不提前 pushState() 添加记录则会回到上一个页面(我们的目的是阻止退回到上一页)
*/
window.history.pushState({
count: count
}, null, `?count=${count++}`);
/*
只有浏览器上的后退按钮和 history 的 back() 可以触发 popstate 事件
history.pushState() 不会触发
*/
window.addEventListener('popstate', function (e) {
alert('xxx');
console.log('监听到 popstate 事件');
console.log(count);
backCount.innerHTML = count;
document.title = `${pageName} page ${count}`;
/*
注意:
调用 window.history.pushState 后再次获取 window.history.state
得到的还是 pushState 前的状态数据,
原因是 history.pushState 后虽然地址栏url 变更了,但是并不会改变文档内容,即使这个时候popstate 事件中的代码可能会改变文档内容。
*/
window.history.pushState({
count: count
}, null, `?count=${count++}`);
})
const back = document.getElementById('back');
const forward = document.getElementById('forward');
back.addEventListener('click', function () {
window.history.back();
})
forward.addEventListener('click', function () {
window.history.forward();
})
}
</script>
2. 详解
1.实现思路
每次进入页面都会提前在浏览器历史记录中新添加一条记录,并且在浏览器回退触发的
popstate
监听器中再次添加历史记录,这样,即使点击了回退,我们看起来也会停留在当前页面
2. 相关重要 API
popstate
事件,当活动历史记录条目更改时触发,也就是点击回退或者调用了history.back()
history.pushState(state, title, url)
用来添加历史记录条目,方法调用后,浏览器地址栏内容会变为预期,但是页面、文档还是会保持之前的展示不变history.back()
与浏览器回退按钮类似效果history.forward()
与浏览器前进按钮类似效果
3. 步骤分解说明
1. 初始化
一下代码用于初始化页面,从地址栏中解析出页面名称,并且从历史记录中解析出
state.count
(第几次回退计数),然后给文档标题重命名,便于通过浏览器查询历史记录
// 初始化
const regex = /\/\w+\./;
const pageName = window.location.pathname
.match(regex)
.pop()
.replace(/\/|\./g, '');
const backCount = document.getElementById('back-count');
let count = (window.history.state && window.history.state.count) || 0;
document.title = `${pageName} page ${count}`;
backCount.innerHTML = count;
2. 正常情况下页面跳转后历史记录查看
只保留初始化部分代码,使用 Chrome 浏览器查看页面跳转后的浏览器记录
查看方法,鼠标右键点击浏览器回退按钮
跳转前
跳转后,浏览器记录中多出了 ‘index page’ 也就是上一页的标题
3. 使用 history.pushState()
添加记录后查看浏览器历史记录信息
在初始化代码下,添加如下代码,然后通过 Chrome 浏览器查看
window.history.pushState({ count: count }, null, `?count=${count++}`);
跳转前
跳转后,可以看到与正常的跳转不同,浏览器记录中多了一条 ‘about page 0’ 也就是 通过
history.pushState()
添加进入的历史信息,这个时候再点击两次回退按钮依然可以会退到主页
4. 添加对浏览器 popstate
事件的监听,动态增加历史记录信息
继续增加如下代码
window.addEventListener('popstate', function(e) {
console.log('监听到 popstate 事件');
console.log(count);
backCount.innerHTML = count;
document.title = `${pageName} page ${count}`;
/*
动态添加历史记录信息
*/
window.history.pushState({ count: count }, null, `?count=${count++}`);
});
跳转前
跳转后,增加了 ‘index page’ 与 ‘about page 0’ 两条记录
点击浏览器回退按钮,可以看到 ‘about page 0’ 消失,但是又新增了一条 ‘about page 1’ 这条记录就是监听 popstate 事件后动态添加的,多次点击回退按钮,可以看到 ‘index page’ 记录之上总是会有 一个新的记录,这样就保证了浏览器不能回退到上一页