我的网站的查询字符串 URL 如下:
?budget=0-&year=0-&kms=0-&so=-1&sc=-1&pn=1
当用户转到下一页(从第 1 页到第 2 页)时:
我们显式增加
pn
(页码加 1)并将其设置在查询字符串 URL 中。
更改了查询字符串:
?budget=0-&year=0-&kms=0-&so=-1&sc=-1&pn=2
我还存储了旧的查询字符串,它看起来像:
?budget=0-&year=0-&kms=0-&so=-1&sc=-1&pn=1
然后我将两者推送到窗口历史记录以更改 URL 并保存以前的内容供浏览器返回:
window.history.pushState(oldQS, null, newQS);
完成此操作后,当我在第2页时,我检查
window.history.state
。它存储我之前的状态:
?budget=0-&year=0-&kms=0-&so=-1&sc=-1&pn=1
我从第 2 页按下浏览器返回,返回到第 1 页。我设置了一个断点:
$(window).on('popstate', function(e) {
console.log(e.originalEvent.state)
});
e.originalEvent.state
是null
。window.history.state
不是 null
并存储正确的值。null
值。 (没有成功。)
在
hashchange
事件上放置断点,但没有帮助,因为 URL 中没有 #。在我的 Javascript 代码上的每个
window.history
函数上放置断点,例如 pushState()
、replaceState()
,但当我按回浏览器时,它们都不会被击中。我不知道还有哪些其他地方/功能可能会从
window.history.state
更改为 null
。
如何通过单击浏览器后退来找出它是如何以及在哪里变为空的?
你问:
我不知道还有哪些其他地方/函数可以将 window.history.state 更改为 null。
如何通过单击浏览器后退来找出它是如何以及在哪里变为空的?
让我们阅读一下 W3C HTML5 规范:
...
History 接口的状态属性必须返回用户代理设置的最后一个值。最初,它的值必须为 null。
结论:当文档加载时,
history.state
最初是null
。
当需要用户代理遍历历史记录到指定条目时,[...],用户代理必须执行以下操作。
...
- 如果该条目是状态对象条目,则令 state 为该状态对象的结构化克隆。否则,让状态为空。
...
- 如果指定条目的Document有最新条目,并且该条目不是指定条目,则让statechanged为true;否则就让它是假的。
...
- 如果状态更改为 true,则使用 PopStateEvent 接口在 Document 的 Window 对象上触发名为 popstate 的可信事件,并将状态属性初始化为状态值。 [...]
结论:当导航回到文档加载时的状态时,
popstate
事件触发的状态是null
。
我为此困惑了很长时间。 @dandavis 在评论中所说的就是问题所在。我使用的解决方案(评论中没有完全提到)是,我需要在页面加载时立即调用replaceState,然后再开始使用pushState。我将初始状态(无论最初渲染页面需要什么)传递给replaceState。