最近,遇到这样一个需求:需要修改浏览器地址栏中的 URL,但不能刷新页面 。传统的 window.location
赋值,会导致页面重载。那么,有没有办法避免刷新,同时更新 URL 呢?
答案是有的! 我们可以使用 History API
或 Hash
机制来实现这一需求(无刷新修改 URL)。
无刷新修改 URL
1、history.pushState():新增历史记录
pushState
能够在不刷新页面的情况下,向浏览器历史记录中添加一条新记录,并更新 URL。注意:这个方法是可以使用户可以使用浏览器的"前进"和"后退"按钮进行导航。
js
history.pushState({ page: 1 }, document.title, '/new-url');
特点:
- URL 变化,但页面不会刷新。
- 新增历史记录,用户可以使用"前进"和"后退"按钮进行导航。
- 适用于单页应用(SPA)。
2、history.replaceState():替换当前历史记录
与 pushState()
类似,但 replaceState()
是替换当前的历史记录,而不会创建新的记录。
js
history.replaceState({ page: 2 }, document.title, '/another-url');
特点:
- URL 变化,但页面不会刷新。
- 不会新增历史记录,用户点击"后退"不会回到之前的 URL。
- 适用于临时性 URL 变更,如动态筛选、修正错误 URL。
3、window.location.hash: 基于 Hash 的 URL 变更
与此同时,我们也通过修改 URL 中的锚点(hash)部分,也能实现无刷新效果:
js
window.location.hash = 'section1';
特点:
- URL 变化但页面不刷新。
hashchange
事件可用于监听 URL 变化。- 适用于简单的前端路由,但不能修改
?
前面的路径。
使用场景对比
方法 | 是否刷新页面 | 是否新增历史记录 | 是否支持参数 | 适用场景 |
---|---|---|---|---|
history.pushState |
❌ | ✅ | ✅ | 用户导航、复杂状态管理 |
history.replaceState |
❌ | ❌ | ✅ | 修正错误 URL、临时状态调整 |
window.location.hash |
❌ | ✅(锚点历史) | ❌(支持锚点参数) | 页面内导航、简单状态更新 |
主要是注意以下两点:
- 是否新增历史记录,决定了用户是否可以"后退"回到之前的 URL。
- 是否可修改查询参数 ,决定了是否可以更新
?query=value
形式的参数。
扩展(如何监控 URL 变化)
- 监听 URL 变化:popstate
js
window.addEventListener('popstate', (event) => {
console.log('用户点击了后退/前进', event.state);
});
- 监听 Hash 变化: hashchange
js
window.addEventListener('hashchange', () => {
console.log('Hash 变化为:', window.location.hash);
})
结语
- 推荐使用
history.pushState()
来更新 URL 并维护历史记录。 - 如果只是想更新 URL 而不影响历史记录,可使用
replaceState()
。 - 如果需要兼容老旧浏览器,或者仅仅是前端页面内导航,可以使用
window.location.hash
。
在实际开发中,我们可以根据需求选择最合适的方案。例如,在 Vue Router 或 React Router 等框架中,已经封装了 History API
,我们可以直接使用 router.push()
或 router.replace()
进行 URL 变更。
希望这篇文章能对你有所帮助、有所借鉴!