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);