在同一窗口中使用localStorage监听更改

f.l*_*nzo 9 javascript events local-storage

我想在同一页面上监听localStorage API中发生的更改(不像规范所说的那样在多个标签中).

我目前正在使用此代码:

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

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

localStorage.setItem('foo', 'bar');
Run Code Online (Sandbox Code Playgroud)

有没有人知道一个vanilla JavaScript方式在一个页面上监听localStorage上的事件(没有jQuery)

Rom*_*iev 15

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

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

  • 为 JavaScript 和重写原始函数欢呼吧! (3认同)
  • 如果您在一个组件中设置值并希望从不同的组件中收听怎么办? (3认同)
  • @f.lorenzo,是的,但也许最好留下来思考_为什么_W3C 合作者决定只为不同的页面提供活动。 (2认同)

小智 12

这个问题的答案对我来说不起作用。我得到了一个Uncaught TypeError: Illegal invocation,所以我编写了自己的代码,可以在大多数环境中运行。它使用代理,这更加安全。

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);
    },
});
Run Code Online (Sandbox Code Playgroud)


Ams*_*ner 7

更新了上面的答案,因为document.createEvent现在是旧的,已弃用的API的一部分.

var originalSetItem = localStorage.setItem;

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

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

  document.dispatchEvent(event);

  originalSetItem.apply(this, arguments);
};

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

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

localStorage.setItem('foo', 'bar'); // Pops an alert
Run Code Online (Sandbox Code Playgroud)

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