【问题标题】:Why does Internet Explorer fire the window "storage" event on the window that stored the data?为什么 Internet Explorer 会在存储数据的窗口上触发窗口“存储”事件?
【发布时间】:2013-08-18 09:39:03
【问题描述】:

Internet Explorer 10 在存储到本地存储的同一窗口上触发窗口“存储”事件。

似乎其他浏览器仅在所有其他窗口上触发该事件,因此我不必担心正在侦听存储事件的窗口对其自身存储作出反应。为什么 IE 会在错误的窗口中触发事件,如何在 IE 中复制标准行为?

【问题讨论】:

    标签: javascript html local-storage


    【解决方案1】:

    微软似乎已经意识到了这个问题,但看起来他们不会很快解决它:https://connect.microsoft.com/IE/feedback/details/774798/localstorage-event-fired-in-source-window

    一种选择是,您可以设计您的侦听器和设置器,以便它们在从已与其状态一致的存储事件中获取信息时不会做出反应或存储。但是,这种设计模式可能比仅在其他窗口上触发存储事件更困难。

    另一种选择是使本地存储在 IE 中的工作方式与在其他浏览器中的工作方式相同。我想出了一个公认的 hacky 但实用的解决方案,我在 IE10 中进行了测试,并希望在 IE8 和 IE9 中工作。我的 javascript 组件不直接收听窗口“存储”事件,而是收听我创建的“事件调度程序”。事件调度程序监听窗口“存储”事件并触发主干事件,除非存储事件源自该窗口。我检查此窗口是否存储此值的方法是使用自定义方法调用 setItem(),该方法为该值创建一个唯一 ID 并跟踪它,如下所示:

    eventDispatcher.set = function(key, value) {
      var storageId = (new Date()).getTime();
      eventDispatcher.idList.push(storageId);
      localStorage.setItem(key, {value: value, id: storageId});
    }
    

    而我的 eventDispatcher 监听存储事件并仅在其创建的 ID 列表不包含此值的 ID 时触发事件,如下所示:

    $(window).on('storage', dispatchStorageEvent);
    function dispatchStorageEvent(event) {
      var newValue = JSON.parse(event.originalEvent.newValue);
      if (eventDispatcher.idList.indexOf(newValue['id']) > -1) {
        return;
      }
      eventDispatcher.trigger("storageEvent:" + event.originalEvent.key, newValue['value']);
    }
    

    您可以添加更多代码来保持 idList 简短并首先将其创建为空数组,但为了清楚起见,我将其省略了。制作一个 eventDispatcher 来处理存储事件有点开销,但它可以使您的开发在浏览器之间保持一致。一个不那么 hacky 的解决方案是使用适当的锁定和排队机制,但这可能非常困难。

    【讨论】:

    【解决方案2】:

    Explorer 在向存储提交新值时已经触发了一个事件。我发现它在我的 IE 11 中触发了 3 次 - 当旧值为 null 时,当新值为 null 时,然后将新值全部存储到存储中。我的解决方法是让监听器进入 setTimeout,我有一秒钟的时间,IE 不再第一次触发它(第一个窗口)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多