在同一窗口上监听 localStorage 的更改

问题描述 投票:0回答:5

我想监听同一页面上 localStorage API 中发生的更改(而不是像规范所说的那样在多个选项卡中)。

我目前正在使用此代码:

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

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

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

有谁知道一种普通的 JavaScript 方式来监听一个页面上 localStorage 上的事件(没有 jQuery)

javascript events local-storage
5个回答
35
投票

更新了上面的答案,因为 document.createEvent 现在是旧的、已弃用的 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


34
投票

由于 JS 是动态语言,只需重写原始函数即可。

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

11
投票

这个问题的答案对我来说不起作用。我得到了

Uncaught TypeError: Illegal invocation
,所以我编写了自己的代码,该代码适用于大多数环境。它使用Proxy,这更安全一些。

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

3
投票

已修复。它也适用于 Chrome 和 Firefox。 解决方案在这里

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

0
投票

文件1

localStorage.setItem("newDataKey", "data");
window.dispatchEvent(new Event("NewDataEvent"));

文件2

window.addEventListener("NewDataEvent", function() {
    console.log("New data was added");
});
© www.soinside.com 2019 - 2024. All rights reserved.