如何解决 IE11 localStorage 事件在 iframe 中触发两次或根本不触发的问题?

2023-12-29

我猜这是一个错误,但我找不到任何关于此的讨论。

众所周知,IE10 将(违反规范)本地触发存储事件(即,在触发事件的同一全局执行上下文中),但 IE11 似乎更偏离规范(http://www.w3.org/TR/webstorage/ http://www.w3.org/TR/webstorage/) 当涉及同域 iframe 时:

  • 如果 iframe 嵌入到触发存储事件的页面中,则该事件将在该 iframe 内触发两次。
  • 如果 iframe 嵌入的页面与触发存储事件的页面不同,则该 iframe 内根本不会触发该事件。
  • 如果事件被触发来自 iframe,它将在本地触发两次,并在嵌入同一页面的任何其他 iframe 中触发两次,但在其他页面的 iframe 中根本不会触发。

您可以通过在两个单独的选项卡中打开以下链接来测试这一点:http://hansifer.com/main.html http://hansifer.com/main.html

有人对这种怪异现象有任何见解吗?

最后测试版本:浏览器 v11.0.9600.16476(更新 2016-08-13:显然是相关的“更新版本”,而不是 IE 的“关于”对话框中报告的“版本”)

错误报告链接: https://connect.microsoft.com/IE/feedback/details/811546/ie11-localstorage-events-fire-twice-or-not-at-all-in-iframes https://connect.microsoft.com/IE/feedback/details/811546/ie11-localstorage-events-fire-twice-or-not-at-all-in-iframes

更新2015-10-26

我刚刚注意到这个问题似乎在 v11.0.9600.18059 中得到了修复,尽管我无法判断该修复何时被删除,因为它似乎没有在任何最近的知识库中被引用。

不幸的是,IE11 localStorage 事件在其他方面仍然存在异常(尽管这些是与本文中提出的问题不同的问题):

  • IE 在调用触发该事件的 localStorage 设置或删除的窗口上下文中引发 localStorage 事件。 localStorage 事件只能在foreign同源的窗口上下文。 (更新:在 EdgeHTML 13.10586 中工作)

  • IE 使用空字符串代替null for e.oldValue/e.newValue添加/删除存储项目时。 (更新:EdgeHTML 13.10586 中仍然存在问题)

  • IE 在设置/删除生效之前或之后不确定地调用 localStorage 事件处理程序,而不是始终在之后。

更新2015-12-24

看来此错误已转移到 Edge(已测试 EdgeHTML 13.10586)

更新2016-02-02

韦尔普,没关系。在 IE v11.63.10586.0 中再次观察到此错误(更新 2016-08-13:显然是相关的“更新版本”,而不是 IE 的“关于”对话框中报告的“版本”)

更新2016-08-13

现在,这个问题似乎在 IE 中得到了修复(更新版本 11.0.34),尽管存储事件仍然在原始窗口中触发,这违反了规范(如上所述的一个已知的长期存在的问题)。

I found this KB https://support.microsoft.com/en-us/kb/3168674包括在IE 2016 年 6 月 14 日安全更新 https://support.microsoft.com/en-us/kb/3160005,尽管根据其描述,它只解决了上面的第二个项目符号。

至于 Edge(已测试 EdgeHTML 14.14393),似乎这个问题现在也已得到解决,但出现了一个新问题:存储事件不会跨同一页面的同源框架触发。

我单独向MS报告了here https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8486073/.


如果您想要限制某个事件被多次调用,无论调用原因如何,请使用标志来阻止后续事件。有几种策略:

.1.基于时间的节流。假设你有一个函数“func”,并且你希望它在 200 毫秒内仅被调用一次:

function func(){
  if (document.func_lock) return;
  document.func_lock=true; // block future calls
  setTimeout(function(){document.func_lock=null;},300);
}

当同时触发多个事件时,您可以预期所有事件都会在 300 毫秒的窗口内到达。上面的代码可以通过利用定时器句柄来简化:

function func(){
  if (document.func_lock) return;
  document.func_lock=setTimeout(function(){return;},300);
}

当定时器到期时,锁会自动解除。

.2.使用回调删除该标志。这个过程很简单,所以我不会在这里发布示例代码。

在标志放置方面,您可以使用任何唯一的 DOM 对象。由于我不知道您的应用程序的上下文,因此我在这里仅使用“文档”。您还可以使用特定于您的应用程序的哈希键,因为您已经在处理本地存储。概念是一样的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何解决 IE11 localStorage 事件在 iframe 中触发两次或根本不触发的问题? 的相关文章

随机推荐