Listen for changes with localStorage on the same window

I want to listen for changes that are happening in the localStorage API on the same page (Not in multiple tabs like the spec says).

I am currently using this code:

var storageHandler = function () {
    alert('storage event 1');
  };

  window.addEventListener("storage", storageHandler, false);

localStorage.setItem('foo', 'bar');

Does anyone know a vanilla JavaScript way to listen to events on localStorage on one page (no jQuery)

Since JS is dynamical language just rewrite original functions.

var originalSetItem = localStorage.setItem; 
localStorage.setItem = function(){
    document.createEvent('Event').initEvent('itemInserted', true, true);
    originalSetItem.apply(this, arguments);
}

Updated above answer, as document.createEvent now is part of an old, deprecated API.

const originalSetItem = localStorage.setItem;

localStorage.setItem = function(key, value) {
  const event = new Event('itemInserted');

  event.value = value; // Optional..
  event.key = key; // Optional..

  document.dispatchEvent(event);

  originalSetItem.apply(this, arguments);
};

const localStorageSetHandler = function(e) {
  alert('localStorage.set("' + e.key + '", "' + e.value + '") was called');
};

document.addEventListener("itemInserted", localStorageSetHandler, false);

localStorage.setItem('foo', 'bar'); // Pops an alert

https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events

The answers to this question didn’t work for me. I got an Uncaught TypeError: Illegal invocation so I wrote my own code which works in most environments. It uses Proxy which is quite a bit safer.

Storage.prototype.setItem = new Proxy(Storage.prototype.setItem, {
    apply(target, thisArg, argumentList) {
        const event = new CustomEvent('localstorage', {
            detail: {
                key: argumentList[0],
                oldValue: thisArg.getItem(argumentList[0]),
                newValue: argumentList[1],
            },
        });
        window.dispatchEvent(event);
        return Reflect.apply(target, thisArg, argumentList);
    },
});

Storage.prototype.removeItem = new Proxy(Storage.prototype.removeItem, {
    apply(target, thisArg, argumentList) {
        const event = new CustomEvent('localstorage', {
            detail: {
                key: argumentList[0],
            },
        });
        window.dispatchEvent(event);
        return Reflect.apply(target, thisArg, argumentList);
    },
});

Storage.prototype.clear = new Proxy(Storage.prototype.clear, {
    apply(target, thisArg, argumentList) {
        const event = new CustomEvent('localstorage', {
            detail: {
                key: '__all__',
            },
        });
        window.dispatchEvent(event);
        return Reflect.apply(target, thisArg, argumentList);
    },
});

Fixed. It works in Chrome and Firefox too. Solution here

var buttonTrigger = document.getElementById('triggerEvent');

buttonTrigger.addEventListener('click', function() {
  window.localStorage.setItem('k1', document.getElementById('storageValue').value);
  window.dispatchEvent(evt);

});

window.addEventListener('storage', function(e) {
  document.getElementById('displayValue').innerHTML = localStorage.getItem('k1');
}, false);


var evt = document.createEvent('StorageEvent'); 

evt.initStorageEvent('storage', false, false, 'k1', 'oldValue', 'newValue',null, window.localStorage); 
      
window.dispatchEvent(evt);


The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .
Read More:   How do I get the http.server from the express app?

Similar Posts