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:
In other words:
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 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?
The storage event of the Window interface fires when a storage area (localStorage) has been modified in the context of another document. ... Log the sampleList item to the console when the storage event fires: window.addEventListener('storage', => { // When local storage changes, dump the list to // the console.
A StorageEvent. Inherits from Event. Returns a string that represents the key changed. The key attribute is null when the change is caused by the storage clear () method. Returns a string with the new value of the key . This value is null when the change has been invoked by storage clear () method, or the key has been removed from the storage.
In addition to the Window interface, the event handler property onstorage is also available on the following targets: Log the sampleList item to the console when the storage event fires: The same action can be achieved using the onstorage event handler property:
You could also overwrite localStorage.setItem so that it fires in the current window in a similar way. Show activity on this post. Yes, you can generate unique id for each tab and compare them, look how this guy did here Another solution I found based on the same idea, generate and compare unique ids.. here Show activity on this post.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With