在js中观察localstorage的变化

Tas*_*ber 11 javascript local-storage typescript reactjs

我有一个单页应用程序,我需要对本地存储中的每个更改做出反应,它看起来像:

    MyComponent {
    
    someFuncWhichIsCalledEveryTimeWhenLocalStorageChanges() {
        console.log('local storage changed!);
    }
    
    funcThatChangesLocalStorage() {
        localstorage.setItem('key',val);
        localstorage.getItem('key')
    }
    
    }
Run Code Online (Sandbox Code Playgroud)

我尝试使用 localstorage 事件:

window.addEventListener('storage', function(event){
       ...
});
Run Code Online (Sandbox Code Playgroud)

但这不起作用......所以我正在考虑使用Observable<>,只是不知道如何正确实现它。

Yan*_*Tay 21

来自 MDN 文档的巨大警告

[ window.addEventListener('storage', ...)] 不会在进行更改的同一页面上工作 - 这实际上是域中其他页面使用存储同步所做的任何更改的一种方式。

所以这可能就是为什么它对你(对我也一样)不起作用的原因——你试图在同一页面的其他部分回应这个听众。


小智 10

您可以使用在对象上创建代理方法的函数

function watchAnyObject(
  object = {},
  methods = [],
  callbackBefore = function () {},
  callbackAfter = function () {},
) {
  for (let method of methods) {
    const original = object[method].bind(object);
    const newMethod = function (...args) {
      callbackBefore(method, ...args);
      const result = original.apply(null, args);
      callbackAfter(method, ...args);
      return result;
    };
    object[method] = newMethod.bind(object);
  }
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它

watchAnyObject(
  window.localStorage,
  ['setItem', 'getItem', 'removeItem'],
  (method, key, ...args) =>
    console.log(`call ${method} with key ${key} and args ${args}`),
);
Run Code Online (Sandbox Code Playgroud)

您可以在组件构造函数中添加侦听器someFuncWhichIsCalledEveryTimeWhenLocalStorageChanges

constructor() {
  watchAnyObject(window.localStorage, ['setItem', 'getItem', 'removeItem'], this.someFuncWhichIsCalledEveryTimeWhenLocalStorageChanges);
}
Run Code Online (Sandbox Code Playgroud)


Mac*_*Mac 8

localDataStorage接口(HTML5 localStorage API 的便捷包装器)可以方便地在发生存储事件的同一页面/选项卡/窗口上触发更改事件。免责声明:我是该界面的作者。

安装localDataStorage后,此示例代码将让您看到这些更改事件:

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
    );
};
document.addEventListener(
    "localDataStorage"
    , nowICanSeeLocalStorageChangeEvents
    , false
);
Run Code Online (Sandbox Code Playgroud)


GMK*_*ain 7

简化的解决方案!

const localStore = localStorage.setItem;

localStorage.setItem = function(key, value) {
  const event = new Event('localUpdated');
        event.key = key; 
        event.value = value; 
  
  document.dispatchEvent(event);
  localStore.apply(this, arguments);
};

const localStoreHandler = function(e) {
  console.log(` localStorage.set('${e.key}', '${e.value}') updated`);
};

document.addEventListener("localUpdated", localStoreHandler, false);


localStorage.setItem('username', 'amoos');

// After 2 second
setTimeout( ()=>  localStorage.setItem('username', 'rifat'), 2000)
Run Code Online (Sandbox Code Playgroud)


Cha*_*ver -2

window.addEventListener('storage', ...) 作品

确保您使用正确的事件属性

这是事件侦听器的基本示例。

  • 这不是OP所要求的。正如已经指出的那样,“存储”的事件侦听器无法在同一页面上工作,因此更改已完成。请阅读 MDN 文档中的注释:https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event (2认同)