为什么Internet Explorer在存储数据的窗口上触发窗口"存储"事件?

Vin*_*ior 13 javascript html5 local-storage

Internet Explorer 10在存储到本地存储的同一窗口上触发窗口"storage"事件.

似乎其他浏览器只在所有其他窗口上触发事件,所以我不必担心一个窗口正在监听存储事件对其自身存储的反应.为什么IE会在错误的窗口中触发事件,如何在IE中复制标准行为?

Vin*_*ior 12

微软似乎意识到了这个问题,但看起来它们似乎不会很快修复它:https://connect.microsoft.com/IE/feedback/details/774798/localstorage-event-fired -in-源窗口

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

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

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

并且我的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']);
}
Run Code Online (Sandbox Code Playgroud)

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

  • 杰西,看看它是如何在这里解决的https://github.com/Shadez/ls-notifier/blob/master/js/notifier.js (2认同)