【问题标题】:observe localstorage changes in js观察js中localstorage的变化
【发布时间】:2018-11-18 21:42:17
【问题描述】:

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

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

我已经尝试使用 localstorage 事件:

window.addEventListener('storage', function(event){
       ...
});

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

【问题讨论】:

  • 试试document.addEventListener
  • @dandavis window.addEventListener 是正确的实现。 Source.
  • @tasha 请查看建议的解决方案是否适合您并更新答案

标签: javascript reactjs typescript local-storage


【解决方案1】:

巨大的警告来自 MDN 文档:

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

所以这可能就是为什么它对您(以及对我)不起作用的原因 - 您试图在同一页面的其他部分响应此侦听器。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      window.addEventListener('storage', ...)works

      确保您使用的是正确的event properties

      Here is a basic example of the event listener.

      【讨论】:

      【解决方案4】:

      当存储区域(localStorage 或 sessionStorage)在另一个文档的上下文中被修改时,将触发存储事件。

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

      【讨论】:

        【解决方案5】:

        如果您想在同一个文档中监听存储更改事件,您可以添加一个存储更改事件发出函数,如下所示。 当你使用localStorage.setItem("xx", "xx"),并在它之后触发这个函数,你会检测到事件~

        export function emitStorageChangedEvent() {
          const iframeEl = document.createElement("iframe");
          iframeEl.style.display = "none";
          document.body.appendChild(iframeEl);
        
          iframeEl.contentWindow?.localStorage.setItem("t", Date.now().toString());
          iframeEl.remove();
        }
        

        【讨论】:

          【解决方案6】:

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

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

          并像这样使用它

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

          你可以在组件构造函数中添加你的监听器someFuncWhichIsCalledEveryTimeWhenLocalStorageChanges

          constructor() {
            watchAnyObject(window.localStorage, ['setItem', 'getItem', 'removeItem'], this.someFuncWhichIsCalledEveryTimeWhenLocalStorageChanges);
          }
          

          【讨论】:

            猜你喜欢
            • 2015-09-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-08-05
            • 2010-11-09
            • 2018-02-26
            • 1970-01-01
            相关资源
            最近更新 更多