主题
History
History API 用于读取和操作浏览器的会话历史记录。最常见的场景是前进、后退,以及单页应用里的地址切换但不整页刷新。
history 是什么
浏览器会为当前标签页维护一条历史记录栈,window.history 暴露的就是对这条记录的访问能力。
js
window.history
history它常用于:
- 调用浏览器后退和前进
- 修改当前地址栏 URL
- 在 SPA 中配合路由记录页面状态
常用属性
history.length
表示当前会话历史记录中的条目数量。
js
console.log(history.length)history.state
返回当前历史条目关联的状态对象。如果当前条目没有通过 pushState() 或 replaceState() 设置过状态,通常为 null。
js
console.log(history.state)history.scrollRestoration
用于控制浏览器在导航时是否自动恢复滚动位置。
js
history.scrollRestoration = 'auto'
history.scrollRestoration = 'manual'auto:浏览器自动恢复滚动位置manual:由应用自己控制滚动恢复
常用方法
back()
等价于浏览器后退按钮。
js
history.back()forward()
等价于浏览器前进按钮。
js
history.forward()go(delta)
按偏移量跳转历史记录:
js
history.go(-1) // 后退一页
history.go(1) // 前进一步
history.go(0) // 刷新当前页pushState()
pushState(state, unused, url) 会新增一条历史记录,并可选地修改地址栏 URL,但不会触发整页刷新。
js
history.pushState({ tab: 'profile' }, '', '/account/profile')这类写法通常用于:
- 单页应用切换路由
- Tab、筛选条件、分页状态进历史栈
- 保持地址栏与页面状态同步
参数说明
state:与当前条目关联的状态对象unused:历史遗留参数,通常传空字符串url:新的地址,必须与当前页面同源
replaceState()
replaceState(state, unused, url) 会替换当前历史记录,而不是新增一条。
js
history.replaceState({ page: 2 }, '', '/list?page=2')它适合:
- 修正当前地址而不希望多出一条历史记录
- 首次渲染后补写默认查询参数
- 更新当前页面状态但不影响返回路径
popstate 事件
当用户点击前进/后退,或脚本调用 history.go() 导致当前条目变化时,通常会触发 popstate 事件。
js
window.addEventListener('popstate', (event) => {
console.log(event.state)
})要点是:
pushState()和replaceState()本身不会触发popstate- 真正切换到其他历史条目时,才会触发该事件
和路由的关系
前端路由常见有两种模式:
- 基于
history.pushState()的 History 路由 - 基于
location.hash的 Hash 路由
History 模式的地址更自然,但服务端通常也要正确处理直达刷新,否则会出现 404。
使用建议
- 需要无刷新修改地址时,优先使用
pushState()或replaceState()。 - 想保留“返回上一步”路径时,用
pushState();只想覆盖当前状态时,用replaceState()。 state适合保存轻量 UI 状态,不适合塞入过大对象。- 直接操作历史记录时,要同时考虑地址、页面内容和返回行为是否一致。
