window.onpopstate,event.state == null?

问题描述 投票:34回答:4

我已经阅读了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)都不会返回任何空值?我错过了什么吗?它没有完全实现吗?

javascript html5 javascript-events
4个回答
57
投票

e.state指的是被推的第二个最后状态。你需要为e.state推动状态至少两次才能成为null。这是因为您应该在第一次加载站点时保存状态,然后每次更改状态时保存状态。


13
投票

我认为这个问题需要更清楚的解释,因为在其他答案中句子“被推迟的第二个状态”可能会导致混淆。

当我们执行history.pushState时,我们正在将历史堆栈推入一个新状态,该状态将成为当前状态(我们可以从导航栏的URL中看到)。

window.onpopstate事件意味着正在弹出顶级历史状态(从堆栈中取出),因此e.state现在将指向堆栈中新的新顶级状态(因为导航栏将指向上一个URL)。


2
投票

我在这个问题上挣扎了好几个小时。太多小时了。 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时没有。

我想了解为什么它现在有效但我已经花了太多时间让它开始工作。如果有人在网上提到了良好的示例代码,那就解释它会很棒。


0
投票

如果您已经了解了撤消/重做堆栈,将会很有帮助,如下图所示。

enter image description here

实际上,历史记录保存在这样的堆栈中。您当前的状态来自当前的堆栈项,我们假设有一个指向它的指针;当你调用history.back()时,指针转到堆栈的旧项目,顺便说一句,onpopstate事件的状态与history.state相同。您将获得当前指向的项目,该项目由history.replaceState修改或由history.pushState添加。

这个过程也解释了为什么history.length不会改变,因为它代表整个堆栈的长度。当你调用history.go(1)时,指针会移回到较新的项目。

当指针位于堆栈的中间位置时,调用history.pushState将导致指针上方的所有项目弹出,并添加新的项目,您也可以看到history'length更改。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.