Javascript window.onpopstate,event.state==null?

Javascript window.onpopstate,event.state==null?,javascript,html,dom-events,Javascript,Html,Dom Events,我已经阅读了几个关于堆栈溢出的问题/答案,并在谷歌上搜索了这个问题,我似乎无法获得事件.state返回的任何内容,除了null 我知道它不适用于jQuery事件,但当我执行类似操作时: window.onpopstate = function (e) { console.log(e.state) } 使用jQuery.ajax成功调用 history.pushState({ lastUrl: data.State }, data.Title, data.UrlKey); Chrom

我已经阅读了几个关于堆栈溢出的问题/答案,并在谷歌上搜索了这个问题,我似乎无法获得
事件.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
,您需要至少推送state两次。这是因为您应该在站点第一次加载时保存状态,之后每次更改状态时保存状态

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

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


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

我为这个问题挣扎了好几个小时。 时间太多了。onpopstate-handler的状态参数 即使我调用了pushState()也为null 在我点击后退按钮之前,我做了很多次

我还发现我的onclick处理程序 调用pushState()导致onpopstate处理程序 被触发。我相信国家管理者 应仅在用户单击 我在网上看到的后退按钮。但是 我的情况似乎不是这样

浏览器中可能有错误吗? 似乎不太可能,因为我也有同样的经历 或者在Chrome和FireFox上出现类似的问题。 但这是可能的。或者可能存在“规范中的错误” 过于复杂,无法正确实施。 没有公共单元测试显示这应该如何工作

最后我找到了一个解决方案,然后 一切都开始起作用了。这是为了 这两个对我的onload处理程序的调用:

pushState (myInitialState, null, href);
pushState (myInitialState, null, href);
所以我必须进行相同的push-state()调用 在onload处理程序中执行两次!在那之后,我的 onpopstate-处理程序开始获取参数 他的状态不是空的,而是我的状态 以前作为参数传递给pushState()

我真的不明白为什么它现在起作用了 为什么我没早点打电话给pushState 一次

我想知道为什么它现在能工作,但我 已经花了太多时间在这件事上了 这很难奏效。如果有人提到好的 在线示例代码解释了这一点
那太好了

如果您了解过撤销/重做堆栈,这将非常有用,如下图所示

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

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


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

正如Jaco Briers提到的那样,
popstate
以我们认为应该的方式工作,我们需要首先存储当您单击浏览器的后退按钮时要返回的初始状态。下面是一个使用jQuery的示例实现:

示例代码

$(window).on({
  // Store initial state
  'load': function() {
    window.history.pushState({
      'html': '<div id="ajax-content">' + $('#ajax-content').html() + '</div>'
    }, '', document.URL);
  },
  // Handle browser Back/Forward button
  'popstate': function(e) {
    var oState = e.originalEvent.state;
    if (oState) {
      $('#ajax-content').replaceWith(oState.html);
    }
  }
});

...

// Update AJAX content
var sUrl = 'https://www.example.com/category?id=123&format=ajax';
$.ajax({
  type: 'GET',
  url: sUrl,
  success: function(sHtml) {
    $('#ajax-content').replaceWith(sHtml);
    window.history.pushState({
      'html': sHtml
    }, '', sUrl);
  }
});
$(窗口)。打开({
//存储初始状态
“加载”:函数(){
window.history.pushState({
'html':'+$('#ajax内容').html()
},'',document.URL);
},
//处理浏览器后退/前进按钮
“popstate”:函数(e){
var oState=e.originalEvent.state;
如果(静态){
$('#ajax content').replacetwith(oState.html);
}
}
});
...
//更新AJAX内容
var sUrl=https://www.example.com/category?id=123&format=ajax';
$.ajax({
键入:“GET”,
网址:sUrl,
成功:功能(sHtml){
$(“#ajax内容”).replacetwith(sHtml);
window.history.pushState({
'html':sHtml
},'',sUrl);
}
});

可能重复@Derek您提供的问题是关于在页面加载时触发popstate。要澄清的是,在popstate激发的任何时候,从pushState函数(即上面示例中的lastUrl)发送的数据在事件对象中都不可用,这就是我要问的问题解决了我在这里问的问题。。。一般评论:我建议不要重载函数
window.onpopstate=function(e){
只需“侦听”它
window.addEventListener(“popstate”),函数(event){
…因为否则您将取消您没有重新编写的其他实现。请参阅下面我对同一问题的描述。每次用户(我)单击链接时,我都会多次调用pushState。但该状态始终为null。只有在我“至少两次”调用pushState()时,它才变为非null在ONLOAD处理程序中。我不明白为什么从onclick-handler多次调用它都不能使它工作。它可能与pushState()的第三个参数的值错误有关吗?谁知道呢。也许吧