点击浏览器返回按钮需要两次才能触发popstate/statechange事件。

6
我有一个包含iframe的页面。用户可以通过按钮点击或菜单选择输入内容,并相应地显示内容。我需要的是,当用户操作iframe时,浏览器将每组iframe参数推送到历史记录中;当用户点击后退按钮时,iframe将使用先前历史记录条目中保存的参数重新加载其内容。我有一段代码执行重新加载,如下所示。
奇怪的是,当我在iframe上进行多个设置(因此添加了多个状态条目到历史记录中),然后点击后退按钮时,它会像这样工作:
假设我在历史记录中有状态4、3、2,现在我在状态5。
1.第一次点击还原到状态4(打印"----state changed----"日志消息) 2.第二次点击重新加载默认内容。不打印"----state changed----",也不调用重新加载代码。 3.第三次点击还原到状态3 4.第四次点击与第二次点击相同 5.第五次点击还原到状态2
因此,在每次成功恢复状态后,需要两次点击才能触发popstate事件(我也尝试过statechanged事件,结果相同)并还原到另一个先前的状态。
有人知道这里发生了什么吗?先感谢您。
History.Adapter.bind(window, "popstate",
    function (event) {
        console.log("----state changed------", History.getState());   
        console.log("----state data------",History.getState().data.state);  

           //code to do reload an iframe to its proper state

    }); 
2个回答

5

我遇到了同样的问题。我们的情况是使用 history.pushState() 更新 URL,然后在更改 <iframe>src 属性之后。通过更改 <iframe>src,我们隐式地告诉浏览器将 iframe 已更改添加到其历史记录中。因此...

  1. 第一次按下返回按钮时,window.historypopstate<iframe> 的 src 属性上被触发,并恢复为其以前的状态。
  2. 第二次按下返回按钮会触发最初推入堆栈的状态的 popstate 事件。

我们的解决方案包括,在我们决定更新 URL 并将状态推入堆栈时,当我们想要更新 <iframe> 时,我们使用 jQuery 替换了 <iframe> 列表,所以...

$("#iFrameID").replaceWith(('<iframe id="iFrameID" src="' + location + '"></iframe>'

通过这样做,我们消除了浏览器历史记录被我们对<iframe>标签的更新所污染的副作用。

1
如果你想在 iframe 中进行更复杂的操作,比如 POST 请求,那么这种方法行不通。虽然理论上可行,但需要编写非常完整的脚本(以处理所有边缘情况),通过 Ajax 发送 POST 请求。到了那个时候,你甚至不需要再设置 iframe 的 URL,只需更新其内容即可。这时,这个简单的解决方案就变得无用了。:/ 我仍在寻找更简单的处理方法... - Domi

0

我曾经遇到过同样的问题。当用户点击返回按钮时,页面并没有回到网站的前一页,而是回到了iframe中的前一页。下面这段代码可以帮助你解决这个问题:

iframe.contentWindow.location.replace(href)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接