I'm guessing it's a bug, but I haven't been able to find any discussion about this.
It's known that IE10 will (against spec) fire storage events locally (ie, within the same global execution context from which the event was triggered), but IE11 seems to stray even further from the spec (/) when it comes to same-domain iframes:
- if the iframe is embedded in the page that triggered the storage event, the event will fire TWICE within that iframe.
- if the iframe is embedded in a page that is different from that which triggered the storage event, the event will not fire at all within that iframe.
- if the event is triggered from an iframe, it will fire TWICE locally and TWICE in any other iframe embedded in the same page, but not at all in iframes of other pages.
You can test this by opening the following link in two separate tabs: .html
Anyone have any insight on this quirkiness?
Last tested version: IE v11.0.9600.16476 (update 2016-08-13: apparently it's the "Update Version" that's relevant, not the "Version" as reported in IE's About dialog)
Link to bug report:
UPDATE 2015-10-26
I just noticed that this seems to be fixed in v11.0.9600.18059, although I can't tell when the fix dropped since it doesn't seem to be referenced in any recent KB.
Unfortunately, IE11 localStorage events are still aberrant in other ways (although these are separate beefs from the issue set forth in this post):
IE raises localStorage events in the window context from which the localStorage set or remove that triggered the event was called. localStorage events should only be raised in foreign window contexts of the same origin. (update: working in EdgeHTML 13.10586)
IE uses empty string instead of
null
fore.oldValue/e.newValue
when storage items are added/removed. (update: still a problem in EdgeHTML 13.10586)IE calls localStorage event handler nondeterministically either BEFORE or AFTER set/remove takes effect instead of consistently AFTER.
UPDATE 2015-12-24
It appears this bug was carried over to Edge (tested EdgeHTML 13.10586)
UPDATE 2016-02-02
Welp, never mind. This bug is once again being observed in IE v11.63.10586.0 (update 2016-08-13: apparently it's the "Update Version" that's relevant, not the "Version" as reported in IE's About dialog)
UPDATE 2016-08-13
This now appears to be fixed in IE (Update Version 11.0.34), although storage events are still fired in the originating window, against spec (a known long-standing issue as mentioned above).
I found this KB that was included in the IE June 14, 2016 Security Update, although according to its description it only addresses the second bullet above.
As for Edge (tested EdgeHTML 14.14393), it seems also that this issue is now fixed, but there's a new problem: storage events are not firing across same-origin frames of the same page.
I reported it separately to MS here.
I'm guessing it's a bug, but I haven't been able to find any discussion about this.
It's known that IE10 will (against spec) fire storage events locally (ie, within the same global execution context from which the event was triggered), but IE11 seems to stray even further from the spec (http://www.w3.org/TR/webstorage/) when it comes to same-domain iframes:
- if the iframe is embedded in the page that triggered the storage event, the event will fire TWICE within that iframe.
- if the iframe is embedded in a page that is different from that which triggered the storage event, the event will not fire at all within that iframe.
- if the event is triggered from an iframe, it will fire TWICE locally and TWICE in any other iframe embedded in the same page, but not at all in iframes of other pages.
You can test this by opening the following link in two separate tabs: http://hansifer.com/main.html
Anyone have any insight on this quirkiness?
Last tested version: IE v11.0.9600.16476 (update 2016-08-13: apparently it's the "Update Version" that's relevant, not the "Version" as reported in IE's About dialog)
Link to bug report: https://connect.microsoft.com/IE/feedback/details/811546/ie11-localstorage-events-fire-twice-or-not-at-all-in-iframes
UPDATE 2015-10-26
I just noticed that this seems to be fixed in v11.0.9600.18059, although I can't tell when the fix dropped since it doesn't seem to be referenced in any recent KB.
Unfortunately, IE11 localStorage events are still aberrant in other ways (although these are separate beefs from the issue set forth in this post):
IE raises localStorage events in the window context from which the localStorage set or remove that triggered the event was called. localStorage events should only be raised in foreign window contexts of the same origin. (update: working in EdgeHTML 13.10586)
IE uses empty string instead of
null
fore.oldValue/e.newValue
when storage items are added/removed. (update: still a problem in EdgeHTML 13.10586)IE calls localStorage event handler nondeterministically either BEFORE or AFTER set/remove takes effect instead of consistently AFTER.
UPDATE 2015-12-24
It appears this bug was carried over to Edge (tested EdgeHTML 13.10586)
UPDATE 2016-02-02
Welp, never mind. This bug is once again being observed in IE v11.63.10586.0 (update 2016-08-13: apparently it's the "Update Version" that's relevant, not the "Version" as reported in IE's About dialog)
UPDATE 2016-08-13
This now appears to be fixed in IE (Update Version 11.0.34), although storage events are still fired in the originating window, against spec (a known long-standing issue as mentioned above).
I found this KB that was included in the IE June 14, 2016 Security Update, although according to its description it only addresses the second bullet above.
As for Edge (tested EdgeHTML 14.14393), it seems also that this issue is now fixed, but there's a new problem: storage events are not firing across same-origin frames of the same page.
I reported it separately to MS here.
Share Improve this question edited Aug 14, 2016 at 0:09 Hans asked Dec 13, 2013 at 11:33 HansHans 8958 silver badges18 bronze badges 8- 10 +1 - I don't have an answer for you, but the bug is definitely legit (tested IE11). Very unusual. I get so irritated with everything that is broken in IE. – Howard Renollet Commented Dec 13, 2013 at 17:40
- 1 @Hans You guys just wasting your time on connect.microsoft.com I have write a lot of bug but they never take care of them seriously. Even sometime crap is released in RTM. IE team is 2 step up. He never respond to a thread on connect until 1-2 year gone. – Anirudha Gupta Commented Dec 14, 2013 at 15:47
- 5 The 'why' can only be answered by Microsoft people I'm afraid. Probably you should rephrase your question to ask for workarounds instead (or migitating factors, i.e. HTML elements or styles that may trigger the buggy behavior) – Stijn de Witt Commented Jan 7, 2014 at 18:34
- 1 Comment to update: now local storage events not firing between same domain iframes, if they're inside other domain web page. – Andrey Commented Nov 19, 2015 at 15:26
- 1 @Andrey Yep, you're right. I've updated the test site to highlight that. FYI, it's by origin, not domain. – Hans Commented Nov 19, 2015 at 21:55
2 Answers
Reset to default 3 +25If you ever want to throttle an event from being called multiple times, regardless the cause for invocation, use a flag to block subsequent events. There are several strategies:
.1. time-based throttling. suppose you have a function "func", and you'd like it to be called only once within 200ms:
function func(){
if (document.func_lock) return;
document.func_lock=true; // block future calls
setTimeout(function(){document.func_lock=null;},300);
}
When multiple events are fired at the same time, you can expect all of them arrive within the 300ms window. The above code can be simplified by taking advantage of the timer handle:
function func(){
if (document.func_lock) return;
document.func_lock=setTimeout(function(){return;},300);
}
When the timer expires, the lock is automatically removed.
.2. Remove the flag by using a callback. The process is trivial so I won't post sample code here.
In terms of flag placement, you can use any unique DOM object. Since I don't know the context of your application, I'll just use "document" here. You can also use hash keys that are particular to your application since you are already dealing with local storage. The concept is the same.
I was able to work around the issue by using window.parent
to register the event in the iframe in this way:
Iframe page
var win = window.parent || window.opener || window;
win.addEventListener('storage', handleLocalStorageEvent, false);
function handleLocalStorageEvent(e) {
console.log('IFRAME local storage event', e);
var sdf = document.getElementById('sdf');
sdf.innerHTML = sdf.innerHTML + 'Storage Event => (' + e.newValue + ')<br>';
}
Disclaimer: Please note that this solution is meant to fix(work around) IE11 issue. By any means it is intended or suggested that this applies to all browser.