需要在后退按钮上单击两次来触发popstate/statechange事件



我有一个包含iframe的页面。iframe可以接受用户的输入(通过单击按钮或菜单选择)并相应地显示内容。我需要的是,当用户操作iframe时,浏览器将每组iframe参数推入历史;当用户单击后退按钮时,iframe将使用前一个历史记录条目中保存的参数重新加载其内容。我有一段代码做重新加载,如下所示。

奇怪的是,当我在iframe上进行多个设置(因此多个状态项添加到历史记录中),然后单击后面,它会像这样工作,

假设我在历史上有状态4,3,2而我现在处于状态5

  1. 第一次点击恢复到状态4(打印"----状态改变----"日志信息
  2. 第二次点击用默认内容重新加载iframe。不打印"----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
    }); 

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

  1. 第一次按回时,window.history的popstate为触发<iframe>的src属性,并恢复到它以前的状态。
  2. 第二次按回将触发popstate事件,用于您最初推入堆栈的状态

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

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

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

我也遇到了同样的问题。后退按钮不是将用户导航到网站上的上一页,而是将用户导航到iframe中的上一页。下面的代码将帮助您解决问题:

iframe.contentWindow.location.replace(href)

最新更新