Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么Internet Explorer会打开窗口;储存;存储数据的窗口上的事件?_Javascript_Html_Local Storage - Fatal编程技术网

Javascript 为什么Internet Explorer会打开窗口;储存;存储数据的窗口上的事件?

Javascript 为什么Internet Explorer会打开窗口;储存;存储数据的窗口上的事件?,javascript,html,local-storage,Javascript,Html,Local Storage,Internet Explorer 10在存储到本地存储的同一窗口上触发窗口“存储”事件 其他浏览器似乎只会在所有其他窗口上触发事件,因此我不必担心一个正在侦听存储事件的窗口会对其自身的存储做出反应。为什么IE在错误的窗口触发事件,我如何在IE中复制标准行为?微软似乎意识到了这个问题,但看起来他们不会很快解决它: 一种选择是,您可以设计侦听器和设置器,以便当它们从存储事件中获取与状态一致的信息时,不会做出反应或存储。但是,这种设计模式可能比仅在其他窗口上触发存储事件更加困难 另一个选择是使本地存

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


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

微软似乎意识到了这个问题,但看起来他们不会很快解决它:

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

另一个选择是使本地存储在IE中的工作方式与在其他浏览器中的工作方式相同。我提出了一个公认的黑客但功能强大的解决方案,我在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});
}
$(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']);
}
我的eventDispatcher只在其创建的ID列表不包含此值的ID时侦听存储事件并触发事件,如下所示:

eventDispatcher.set = function(key, value) {
  var storageId = (new Date()).getTime();
  eventDispatcher.idList.push(storageId);
  localStorage.setItem(key, {value: value, id: storageId});
}
$(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处理存储事件有点开销,但它可以使您的开发在浏览器之间保持一致。一个不太老套的解决方案将使用适当的锁定和排队机制,但这可能非常困难。

资源管理器在向存储提交新值时已经触发了一个事件。我发现它在我的IE 11中触发了三次——当旧值为null时,当新值为null时,然后将新值存储到存储器中。我的解决方法是将侦听器设置为setTimeout,我只需一秒钟,IE就不会再第一次触发它(第一个窗口)。

您是否有关于cust事件调度器外观的要点?Jesse,看看它是如何解决的,请您提供更多详细信息?我真的还没拿到\