为什么Internet Explorer会触发窗口“存储”?存储数据的窗口上的事件? [英] Why does Internet Explorer fire the window "storage" event on the window that stored the data?
问题描述
Internet Explorer 10在存储到本地存储的同一窗口上触发窗口storage事件。
Internet Explorer 10 fires the window "storage" event on the same window that stored to local storage.
似乎其他浏览器仅在所有其他浏览器上触发事件windows,所以我不必担心一个窗口正在监听存储事件对它自己的存储作出反应。为什么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似乎请注意这个问题,但看起来他们不会很快修复它: https://connect.microsoft.com/IE/feedback/details/774798/localstorage-event-fired-in-source-window
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中以相同的方式工作它适用于其他浏览器。我提出了一个公认的hacky但功能性的解决方案,我在IE10中测试过,期望在IE8和IE9中工作。我的javascript组件不直接监听窗口storage事件,而是听我创建的事件调度程序。事件调度程序侦听窗口storage事件并触发主干事件,除非源于该窗口的存储事件。我检查此窗口是否存储此值的方法是使用自定义方法调用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处理存储事件需要一些开销,但它可以使您的开发在浏览器之间保持一致。一个不太常见的解决方案将使用适当的锁定和排队机制,但这可能非常困难。
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会触发窗口“存储”?存储数据的窗口上的事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!