携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情。
前言
对于 Web 开发者而言,history.back()
作为经典的回退 API,有着不可撼动的地位。但是我在使用过程中,却发现这个 API 存在无法回退的现象,百思不得其解。最后在各种尝试下,发现是我的使用存在误区,对 history 对象的理解不够精确,才导致在用户视角上的页面回退失败。
history 对象
history 对象表示当前窗口首次使用以来用户的导航历史记录。
导航
history.go()
方法可以在用户历史记录中实现导航功能,即页面前进和后退。
history.back()
方法是 history.go(-1)
方法的简写,模拟了浏览器的后退按钮,提供回退功能。
history.forward()
方法是 history.go(1)
方法的简写,模拟了浏览器的前进按钮,提供前进功能。
状态管理
状态管理 API 方法可以改变浏览器 URL 而不会加载新页面。
history.pushState()
方法会将新的状态信息推到历史记录中。
history.replaceState()
方法可以更新当前状态,而不会创建新的历史记录。
实践
为什么会介绍上面这两个 history 对象提供的功能呢?因为是实际开发中,产品要求可以根据用户在页面上的行为来更新 URL 而不刷新页面,既保证用户的浏览体验,又可以确保用户分享出去的 URL 是有状态的。
初入茅庐的我勇敢的接下了这个任务,并自信的使用 history.pushState('', '', newURL)
来实时改变 URL,使用 history.back()
作为回退按钮点击触发时调用的功能。结果,就是回退按钮失效了。
原因
其实原因很简单,history.pushState()
创建了新的历史记录,当用户从 A 页面进入 B 页面,并在 B1 页面进行操作触发 history.pushState()
时,虽然 B1 页面内容不变,但是历史栈中新增了 B2 的记录,所以此时用户点击回退按钮触发 history.back()
时页面不变,看起来就是回退失败的场景,实际上用户已经从 B2 页面回退到了 B1 页面。
总结
这个小坑出现的原因是我对 history 对象的理解有误,在翻阅了 history.pushState()
的官方文档后,很容易就能发现,但是出于对自己知识掌握的自信,我在排查问题时没有想到要去翻阅文档,而是在网络上搜索各种类似的问题与解决方案,但是大家的问题并不相似,可以说是白费功夫。