32

Is there any way to detect any change in HTML5 localStorage and then call certain functions if there is any change indeed? I have certain keys stored with names as "e1", "e2", "e3", and so on...

i want to detect if any key is removed or added and then trigger some functions if there is any change...

Devashish
  • 1,260
  • 1
  • 10
  • 21
  • possible duplicate of [How to bind to localStorage change event using jQuery for all browsers?](http://stackoverflow.com/questions/4671852/how-to-bind-to-localstorage-change-event-using-jquery-for-all-browsers) – Blazemonger Apr 10 '14 at 17:19

2 Answers2

43

According to specs Storage interface emits storage event on global objects which it affects.

So in your case you may just add handler

window.addEventListener("storage", function () {
    // do your checks to detect
    // changes in "e1", "e2" & "e3" here
}, false);

There is no need for jQuery even.

nilfalse
  • 2,380
  • 2
  • 19
  • 16
  • 10
    @madprops because events will be fired in secondary tabs (at same domain), not in master tab. https://stackoverflow.com/a/4689033/1221082 – Denis Nov 09 '17 at 15:09
  • 2
    According to spec, this won't be fired on same page or tab making the change. Only on other tabs. – Aaron Mar 10 '20 at 19:27
  • @Aaron Whats a solution to detect changes in same tab/page? – Marc Sep 15 '22 at 17:57
  • You could always create an Iframe within the page that attaches the listener. – CherryDT Nov 12 '22 at 21:55
0

The localDataStorage interface (a handy wrapper for the HTML5 localStorage API) conveniently fires change events on the same page/tab/window in which the storage event occurred. (Disclaimer: I am the author of the interface.)

Once you install localDataStorage, this sample code will let you see those change events (and fire off your own required logic in response):

function nowICanSeeLocalStorageChangeEvents( e ) {
    console.log(
        "subscriber: "    + e.currentTarget.nodeName + "\n" +
        "timestamp: "     + e.detail.timestamp + " (" + new Date( e.detail.timestamp ) + ")" + "\n" +
        "prefix: "        + e.detail.prefix    + "\n" +
        "message: "       + e.detail.message   + "\n" +
        "method: "        + e.detail.method    + "\n" +
        "key: "           + e.detail.key       + "\n" +
        "old value: "     + e.detail.oldval    + "\n" +
        "new value: "     + e.detail.newval    + "\n" +
        "old data type: " + e.detail.oldtype   + "\n" +
        "new data type: " + e.detail.newtype
    );

    // localstorage has changed; invoke your custom logic here passing in the key that changed
    myCustomFunction( e.detail.key ); 
};
document.addEventListener(
    "localDataStorage"
    , nowICanSeeLocalStorageChangeEvents
    , false
);

The example nowICanSeeLocalStorageChangeEvents() function just spits out key details, but you could easily use it to take specific actions like you mentioned.

For example, if you add a new key

lds.set( 'e2', 101 );

then you'll get something like

message: create new key
method: set
key: e2
old value: undefined
new value: 101
old data type: undefined
new data type: integer

When you delete a key

lds.remove( 'e2' );

then you'll see something like

message: remove key
method: remove
key: e2
old value: 101
new value: undefined
old data type: integer
new data type: undefined

so you can easily respond to local storage key events.

Additionally, via the Broadcast Channel API, localDataStorage can keep other tabs/windows in sync across the same origin. To monitor events, listen on the default channel with a snippet like this

const myChannel = new BroadcastChannel( 'localDataStorage' );
channel.addEventListener( 'message', (event) => {
    console.log( event.data );
});

where the listener will receive a JSON of event data.

Mac
  • 1,432
  • 21
  • 27
  • 5
    Why does ugly(fied) code even exist on github? We people like to be free and open! You should never use a open-source licence (like BSD) to pulish your close source software – alphakevin May 08 '21 at 07:23
  • localStorage.clear() doesn't seem to fire the listener for whatever reason. Is it on purpose? – Eli Mashiah Oct 25 '21 at 10:56
  • @EliMashiah: The clear() method does not fire the the custom change event. Good catch! This is an oversight on my part. I'll add this fix to the next minor release. Thanks again! – Mac Oct 26 '21 at 18:30
  • @EliMashiah: patch 1.3.1 of [localStorage](https://github.com/macmcmeans/localDataStorage) fixes the error you discovered. Thanks for spotting it! – Mac Feb 21 '22 at 23:44
  • I need to detect if a local storage value has changed in the same app, but in another browser tab. As I read your post, that's not possible? – Jette Aug 05 '22 at 13:14
  • 1
    @Jette: As written, my wrapper will not post events to other tabs/windows in the same domain. But you could easily implement Broadcast Channel API to copy a localDataStorage event and post it to another tab in another window (same domain). – Mac Aug 07 '22 at 11:45
  • 1
    @Jette: You're welcome. My next major revision will include broadcast channel capability, inspired by your question. – Mac Aug 07 '22 at 23:21
  • 1
    @Jette: I released version 3 that broadcasts change events. Hope it helps! – Mac Aug 13 '22 at 00:43
  • 1
    @Mac that's amazing. Looking forward to trying it out :-D – Jette Aug 16 '22 at 06:53