12

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?

Christian Heine
  • 346
  • 2
  • 11
  • 2
    Happening for me too on this Safari version. Can't reproduce it on old safari versions. – Danteinus Apr 19 '20 at 06:17
  • 1
    Thanks for trying this out! Seems this is a bug... Just found it on Bugzilla: https://bugs.webkit.org/show_bug.cgi?id=210512. I think I'll go for a workaround then. *Sigh* – Christian Heine Apr 20 '20 at 04:16
  • This is happening for me, too on Safari 15.5 on macbook and latest iphones – lwdthe1 Nov 15 '22 at 23:11

1 Answers1

7

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.

flaesh
  • 262
  • 5
  • 17
  • Hi, thanks for the answer. Will certainly give this a look. In the meantime, I went for a small self-written utility class which tracks which window is currently open (mostly built around load/unload/visibilitychange events). I still believe this whole behavior is a bug, though. – Christian Heine Jun 04 '20 at 01:22