12

I have tried to follow the examples on the Safari Developer Site.

The documentation suggests adding an event listener like so:

window.addEventListener('storage', storage_handler, false);

And then setting your handler function like this:

function storage_handler(evt)
{
    alert('The modified key was '+evt.key);
    alert('The original value was '+evt.oldValue);
    alert('The new value is '+evt.newValue);
    alert('The URL of the page that made the change was '+evt.url);
    alert('The window where the change was made was '+evt.source);
}

But I can't seem to get this code to work on my machine (OS X 10.6, Safari 5.01) nor on Safari on my iPhone 3GS (iOS 4.02).

This article offers a separate method:

window.onload = function() {
    ...
    document.body.setAttribute("onstorage", "handleOnStorage();");
}

function handleOnStorage() {
    if (window.event && window.event.key.indexOf("index::") == 0){
        $("stats").innerHTML = "";
        displayStats();
    }
}

But I haven't had any luck with that either.

Am I doing something wrong? Is this a bug?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Jason
  • 463
  • 1
  • 3
  • 11
  • 1
    I fixed up the links in your question for you; you should be able to add more links soon, once you get a bit more rep. Sadly I don't know the answer to your question. Hope someone else can help! – Brian Campbell Aug 25 '10 at 05:09
  • A good demo with its code snippet is already available [here](http://html5demos.com/storage-events) which help understand the concept and how it is working. http://html5demos.com/storage-events – Muhammad Soliman Sep 19 '15 at 21:33
  • still you have this link that might help too in understanding sessionStorage very well https://www.nczonline.net/blog/2009/07/21/introduction-to-sessionstorage/ – Muhammad Soliman Sep 20 '15 at 11:14

4 Answers4

20

After investigating further (and with the help from a friend) I discovered that the storage_handler method is called not when the value of a localstorage value changes on the page in my current window or tab, but when it changes in another tab.

For example, if I have the two tabs open, and have controls in the pages in each tab to change localstorage settings, then when I hit the control in the first tab, the storage_handler method is called in the other tab.

Jason
  • 463
  • 1
  • 3
  • 11
  • Have you found a reliable source? Could you provide us with it? I couldn't infer that from the spec https://www.w3.org/TR/webstorage/#sessionStorageEvent. But in any case I'm having trouble interpreting, especially the section where it mentions a "fully active" Document. – leods92 Apr 25 '17 at 19:17
  • For firefox, chrome and IE 11, storage handler method called on same tab or window. But for ipad safari it get called it other tab change localStorage. – RpR Apr 02 '18 at 14:16
  • @leods92 Here is some documentation https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API#Example – Akshay Gupta Aug 14 '18 at 19:08
3

If you want to perform some action after the objects are saved in localstorage on the same page you can manually call the function after calling localStorage.setItem and call the same function from the storage eventlistener to handle multiple tabs.

subham.saha1004
  • 794
  • 8
  • 6
1

I realize this is asking about Safari but, per the Mozilla Developer Network, the StorageEvent is only fired if the web storage object is changed from outside the page, e.g., in another tab.

https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API

Scroll down to "Responding to storage changes with the StorageEvent".

(I would have added this as a comment to the accepted answer but I don't have the rep for that.)

nklatt
  • 31
  • 1
  • 5
0

You can send a storage event every time you set the local storage

const favorites: null | string =
  localStorage.getItem(favoritesKey);
localStorage.setItem(
  favoriteKey,
  JSON.stringify(
      favorites === null
      ? [id]
      : [...JSON.parse(favorites), id]
  )
);

window.dispatchEvent(new Event("storage"));

Then the following will trigger

useEffect(() => {
  const listener = () => {
    const favorites: null | string = localStorage.getItem(favoriteKey);
    if (favorites !== null) {
      setState(JSON.parse(favorites));
    }
  };
  window.addEventListener("storage", listener);
  return () => {
    window.removeEventListener("storage", listener);
  };
}, []);
CESCO
  • 7,305
  • 8
  • 51
  • 83