为什么Internet Explorer会触发窗口“& storage&"存储数据的窗口上发生事件? [英] Why does Internet Explorer fire the window "storage" event on the window that stored the data?
问题描述
Internet Explorer 10在存储到本地存储的同一窗口上触发窗口存储"事件.
Internet Explorer 10 fires the window "storage" event on the same window that stored to local storage.
似乎其他浏览器仅在所有其他窗口上触发该事件,因此我不必担心正在监听存储事件对其自身存储作出反应的窗口.为什么IE会在错误的窗口中触发事件,如何在IE中复制标准行为?
It seems like other browsers only fire the event on all other windows, so I don't have to worry about a window that's listening to storage events reacting to its own storing. Why does IE fire the event in the wrong window, and how can I replicate the standard behavior in IE?
推荐答案
Microsoft似乎已经意识到了这个问题,但是看起来他们不会很快解决这个问题:
Microsoft seems to be aware of the issue, but it doesn't look like they're going to fix it any time soon: https://connect.microsoft.com/IE/feedback/details/774798/localstorage-event-fired-in-source-window
一个选择是,您可以设计您的侦听器和设置器,以使它们在从已经与其状态保持一致的存储事件中获取信息时不做出反应或存储.但是,这种设计模式比仅依靠在其他窗口上触发存储事件要困难得多.
One option is that you can design your listeners and setters so that they don't react or store when they get information from a storage event that's already consistent with their state. However, this design pattern can be more difficult than relying on the storage event only firing on other windows.
另一个选择是使本地存储在IE中的工作方式与在其他浏览器中的工作方式相同.我想出了一个公认的功能强大但功能强大的解决方案,该解决方案已在IE10中进行了测试,并有望在IE8和IE9中工作.我的javascript组件不直接监听窗口存储"事件,而是监听我创建的事件分配器".事件分派器侦听窗口存储"事件,并触发主干事件,除非该窗口中发起了存储事件.我检查此窗口是否存储此值的方式是通过使用自定义方法来调用setItem(),该方法将为该值创建唯一的ID并对其进行跟踪,如下所示:
Another option is to make local storage work the same way in IE that it works in other browsers. I came up with an admittedly hacky but functional solution that I tested in IE10 and expect to work in IE8 and IE9. My javascript components don't listen to the window "storage" event directly but instead listen to an 'event dispatcher' I created. The event dispatcher listens to the window "storage" event and triggers a backbone event UNLESS the storage event originated in that window. The way I check if this window stored this value is by using a custom method for calling setItem() that creates a unique ID for the value and keeps track of it, like this:
eventDispatcher.set = function(key, value) {
var storageId = (new Date()).getTime();
eventDispatcher.idList.push(storageId);
localStorage.setItem(key, {value: value, id: storageId});
}
并且我的eventDispatcher侦听存储事件并仅在其创建的ID列表中不包含该值的ID时触发事件,如下所示:
And my eventDispatcher listens to storage events and triggers an event only if its list of IDs it created doesn't contain this value's ID, like this:
$(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的解决方案将使用适当的锁定和排队机制,但这可能非常困难.
There's a bit more code you can add to keep the idList short and to create it as an empty array in the first place, but I left that out for the sake of clarity. Making an eventDispatcher to handle storage events is a bit of overhead, but it can make your development consistent between browsers. A less hacky solution would use a proper locking and queueing mechanism, but that can be very difficult.
这篇关于为什么Internet Explorer会触发窗口“& storage&"存储数据的窗口上发生事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!