Safari在同一标签中触发StorageEvent [英] Safari fires StorageEvent in same tab

查看:165
本文介绍了Safari在同一标签中触发StorageEvent的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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




  • 项目的值已更改

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



换句话说:




  • 假设我有两个打开的选项卡(A和B)

  • 两者都收听对存储的更改

  • 其中一个选项卡(A)向本地存储写入内容

  • 另一个选项卡(B)应该接收到存储事件



在Chrome,Firefox&歌剧。但是在Safari中,它也会在同一标签中触发。



此代码将复制此代码(可在控制台中的任何站点上使用):

  window.addEventListener('storage',event => console.log(event)); 
window.localStorage.setItem('foo','bar');




  • 在Chrome / Firefox / Opera中不会记录任何内容(预期行为)

  • 在Safari中,存储事件将记录在同一窗口中



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



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

解决方案

IE11,如所述此处。解决方案是按照此处中所述检查当前标签是否在焦点上。

因此,在您的代码中:

 函数处理程序(事件){
if(! document.hasFocus()){
//继续执行逻辑
}
}
window.addEventListener('storage',handler);

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


I am experiencing a strange issue in Safari (Version 13.1).

Use case: I am synchronizing data between various open tabs. This is implemented by writing to local storage and listening to the "storage" event.

According my understanding (and MDN: https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event), the storage event should be fired when something is written to local storage and two conditions are fulfilled:

  • the value for the item has changed
  • this change is originating from the same domain, but a different document (i.e. other tab/window)

In other words:

  • Let's say I have two open tabs (A and B)
  • Both listen for changes to "storage"
  • One of the tabs (A) writes something to local storage
  • Only the other tab (B) should receive the "storage" event

This works perfectly fine in Chrome, Firefox & Opera. But in Safari it is fired within the same tab as well.

This code will replicate this (works on any site in the console):

window.addEventListener('storage', event => console.log(event));
window.localStorage.setItem('foo', 'bar');

  • In Chrome/Firefox/Opera nothing will be logged (expected behavior)
  • In Safari, a storage event will be logged in the same window

In addition, the event itself does not seem to have sufficient information to identify which tab has triggered it. I am pondering to write another helper with a unique key per open tab and write that to local storage and listen for changes to it. But before I do that I wanted to see if I am missing something. I know there are some libraries to message other tabs, but I am reluctant to introduce a dedicated library for something as basic as this.

Question: Am I missing something? Is there a way to let the storage event in Safari only fire when something is written from other tabs?

解决方案

This also happens on IE11, as described here and here. The solution is to check, whether your current tab is in focus, as described here.

So, in your code:

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

I'd also suggest to handle the IE issue, in case your app needs it, as described in the above answers. You can do that by detecting the browser and enhancing the above logic.

这篇关于Safari在同一标签中触发StorageEvent的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆