使用pushState/onpopstate时回退到第5步却输出第4步的问题
关于pushState与popState的历史状态异常问题解答
嘿,我来帮你拆解这两个问题的根源,其实都是浏览器历史栈的工作机制和Chrome的UI小特性在搞鬼:
一、点击历史第5步时popState输出第4步page值的原因
首先得理清楚历史栈的结构和popState事件的触发逻辑:
- 假设你打开的第一个页面是「初始页」,之后每访问一个新页面就执行一次
pushState,那你的历史栈应该是这样的:[初始页(无自定义state), 页1(存了page=1的state), 页2(page=2), ..., 页10(page=10)] - 当你在「页10」时,直接点历史记录里的「第5步」,这里容易踩坑的点是:历史记录的显示顺序和栈的索引不是完全对应的。如果你的「第5步」是指从初始页开始数的第5个条目,那它对应的是栈里索引为4的条目(因为栈是从0开始计数的),而你的
page字段是从1开始算的,自然就会出现标题显示的是第5步,但popState输出的是第4步的page值。 - 另外还有一种可能:你是先加载页面内容、更新标题,再执行
pushState。这时候初始页根本没被存入自定义state,当你到页10时,历史栈里的自定义state条目是10个(对应页1到页10),初始页是第0个无state的“隐形”条目。你点历史记录里的第5步,实际跳的是栈里第4个带state的条目,所以输出的page就是4。
二、Chrome点击二次后才显示所有历史步骤的原因
这个完全是Chrome的UI优化搞的鬼:
- 当你连续用
pushState添加多条AJAX跳转的历史记录时,Chrome会默认把这些连续的记录合并成一个“组”,在历史记录面板里只显示最顶部的那条,不会直接展开所有步骤——它觉得你可能不想看到一堆连续的AJAX跳转记录,帮你做了折叠。 - 但当你点击一次回退按钮后,Chrome就会打破这个合并组,此时再打开历史记录面板,就能看到所有的历史步骤了。这个是Chrome独有的UI行为,和你的代码逻辑没关系,换Firefox之类的浏览器可能直接就显示所有记录了。
内容的提问来源于stack exchange,提问作者OlegKhorev
相关产品推荐
相关产品推荐

