我已经阅读了Stack Overflow上的几个问题/答案并用谷歌搜索了这个问题,我似乎无法让event.state
回来除了null
。
我知道它不适用于jQuery事件,但当我做这样的事情时:
window.onpopstate = function (e) {
console.log(e.state)
}
随着jQuery.ajax成功调用的东西
history.pushState({ lastUrl: data.State }, data.Title, data.UrlKey);
Chrome(v19)或Firefox(v12)都不会返回任何空值?我错过了什么吗?它没有完全实现吗?
e.state
指的是被推的第二个最后状态。你需要为e.state
推动状态至少两次才能成为null
。这是因为您应该在第一次加载站点时保存状态,然后每次更改状态时保存状态。
我认为这个问题需要更清楚的解释,因为在其他答案中句子“被推迟的第二个状态”可能会导致混淆。
当我们执行history.pushState时,我们正在将历史堆栈推入一个新状态,该状态将成为当前状态(我们可以从导航栏的URL中看到)。
window.onpopstate事件意味着正在弹出顶级历史状态(从堆栈中取出),因此e.state现在将指向堆栈中新的新顶级状态(因为导航栏将指向上一个URL)。
我在这个问题上挣扎了好几个小时。太多小时了。 onpopstate -handler的state-argument为null,即使我在单击后退按钮之前多次调用了pushState()。
我还观察到我的onclick-handler调用了pushState()导致onpopstate -handler被触发。我相信onpopstate -handler应该只是因为用户点击我在网上看到的后退按钮而被调用。但在我的情况下似乎并非如此。
浏览器中可能有错误吗?似乎不太可能,因为我在Chrome和FireFox上都有相同或类似的问题。但可能。或者可能是“规范中的错误”太复杂而无法正确实施。没有公共单元测试显示这应该如何工作。
最后,我找到了一个解决方案,之后一切开始工作。将这两个调用放入我的onload-handler中:
pushState (myInitialState, null, href);
pushState (myInitialState, null, href);
所以我必须在onload-handler中进行相同的push-state()调用TWICE!之后我的onpopstate -handler开始获取其状态为非null的参数但是我之前作为参数传递给pushState()的状态。
我真的不明白为什么它现在有效以及为什么它在早些时候我只调用pushState时没有。
我想了解为什么它现在有效但我已经花了太多时间让它开始工作。如果有人在网上提到了良好的示例代码,那就解释它会很棒。
如果您已经了解了撤消/重做堆栈,将会很有帮助,如下图所示。
实际上,历史记录保存在这样的堆栈中。您当前的状态来自当前的堆栈项,我们假设有一个指向它的指针;当你调用history.back()
时,指针转到堆栈的旧项目,顺便说一句,onpopstate
事件的状态与history.state
相同。您将获得当前指向的项目,该项目由history.replaceState
修改或由history.pushState
添加。
这个过程也解释了为什么history.length
不会改变,因为它代表整个堆栈的长度。当你调用history.go(1)
时,指针会移回到较新的项目。
当指针位于堆栈的中间位置时,调用history.pushState
将导致指针上方的所有项目弹出,并添加新的项目,您也可以看到history'length
更改。