Why does Internet Explorer fire the window "storage" event on the window that stored the data?

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.

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});
}

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']);
}

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.