【问题标题】:Safari fires StorageEvent in same tabSafari 在同一选项卡中触发 StorageEvent
【发布时间】:2020-06-03 05:22:47
【问题描述】:

我在 Safari(13.1 版)中遇到了一个奇怪的问题。

用例:我正在各个打开的选项卡之间同步数据。这是通过写入本地存储并监听“存储”事件来实现的。

根据我的理解(和 MDN:https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event),当某些内容写入本地存储并且满足两个条件时,应该触发存储事件:

  • 项目的值已更改
  • 此更改源自同一域,但来自不同的文档(即其他选项卡/窗口)

换句话说:

  • 假设我有两个打开的选项卡(A 和 B)
  • 两者都监听“存储”的变化
  • 其中一个选项卡 (A) 将某些内容写入本地存储
  • 只有另一个标签 (B) 应该接收“存储”事件

这在 Chrome、Firefox 和 Opera 中运行良好。但在 Safari 中,它也会在同一个选项卡中触发。

此代码将复制此代码(适用于控制台中的任何站点):

window.addEventListener('storage', event => console.log(event));
window.localStorage.setItem('foo', 'bar');
  • 在 Chrome/Firefox/Opera 中不会记录任何内容(预期行为)
  • 在 Safari 中,存储事件将记录在同一窗口中

此外,事件本身似乎没有足够的信息来确定是哪个选项卡触发了它。我正在考虑为每个打开的选项卡编写另一个具有唯一键的助手,并将其写入本地存储并监听它的更改。但在我这样做之前,我想看看我是否遗漏了什么。我知道有一些库可以向其他选项卡发送消息,但我不愿意为像这样基本的东西引入一个专用库。

问题:我错过了什么吗?有没有办法让 Safari 中的存储事件仅在从其他选项卡写入内容时触发?

【问题讨论】:

  • 这个 Safari 版本也发生在我身上。无法在旧版 Safari 上重现它。
  • 感谢您试用!似乎这是一个错误......刚刚在 Bugzilla 上找到它:bugs.webkit.org/show_bug.cgi?id=210512。我想我会去找一个解决方法。 叹息

标签: javascript html safari dom-events


【解决方案1】:

这也发生在 IE11 上,如 herehere 所述。解决方案是检查您当前的标签是否处于焦点,如here 所述。

所以,在你的代码中:

function handler (event) {
  if (!document.hasFocus()) {
    // continue with your logic
  }
}
window.addEventListener('storage', handler);

我还建议处理 IE 问题,以防您的应用需要它,如上述答案中所述。您可以通过检测浏览器并增强上述逻辑来做到这一点。

【讨论】:

  • 您好,感谢您的回答。一定会看看这个。与此同时,我使用了一个小型的自写实用程序类,它跟踪当前打开的窗口(主要围绕加载/卸载/可见性更改事件构建)。不过,我仍然相信这整个行为是一个错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-24
  • 2019-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多