2013-08-27 23 views
10

在Internet Explorer 9的& 10,localStorage的执行触发事件意外(大螺纹在这里:Bug with Chrome's localStorage implementation?IE localStorage的情况下发挥失常

有谁知道的方法,从射击标签停止storage事件引发的变化在Internet Explorer中?

例如,当添加按钮被点击以下不应该显示一个警告,但它在IE浏览器:

小提琴:http://jsfiddle.net/MKFLs/

<!DOCTYPE html> 
<html> 
    <head> 
    <title>Chrome localStorage Test</title> 
    <script type="text/javascript" > 

     var handle_storage = function() { 
     alert('storage event'); 
     }; 

     window.addEventListener("storage", handle_storage, false); 

    </script> 
    </head> 
    <body> 
    <button id="add" onclick="localStorage.setItem('a','test')">Add</button> 
    <button id="clear" onclick="localStorage.clear()">Clear</button> 
    </body> 
</html> 

编辑: 在一个侧面说明,我在这里开了一个MS错误。 https://connect.microsoft.com/IE/feedback/details/798684/ie-localstorage-event-misfired

也许它不会关闭.....

+0

@EricLaw感谢编辑:) – Jesse

回答

11

更改你的脚本如下防止在聚焦窗口中的任何存储事件的处理。

这不完全是你问的,因为我相信这需要一个补丁到浏览器,但它会导致IE 9/10符合规范,同时对其他浏览器没有不利影响(除了全局和听众)。

<script type="text/javascript" > 
     var focused; 

     window.addEventListener('focus', function(){focused=1;}, false); 
     window.addEventListener('blur', function(){focused=0;}, false); 

     var handle_storage = function (e) { 
     if(!focused) 
      alert("Storage",focused); 
     }; 

     window.addEventListener("storage", handle_storage, false); 

</script> 

有关更新的符合性行为,请参见this fiddle

编辑:下面也适用,并在窗口焦点的运行时检查的成本避免了听众:

<script type="text/javascript" > 

     var handle_storage = function (e) { 
     if(!document.hasFocus()) 
      alert("Storage"); 
     }; 

     window.addEventListener("storage", handle_storage, false); 

</script> 
+0

一个并不需要额外的变量:http://stackoverflow.com/a/8235434/255363(我测试 - 它适用于存在事件的IE9 +) – kirilloid

0

如果您正在寻找解决方法,你可以写为包装用的localStorage信号。

试试这个(未测试):

var BetterStorage = { 
    _semaphore: false, 
    setItem: function(key, item) { 
     var that = this; 
     this._semaphore = 1; // only this tab 
     localStorage.setItem(key, item); 
     this._semaphore = 0; 
     // or setTimeout(function(){that._semaphore = 0}, 10) 
     // based on event-fire time (immedietaly or after short delay?) 
     // not tested 
    }, 
    getItem: function() {/*code*/}, 
    createHandler: function(f) { 
     var that = this; 
     return function(e){ 
      if (that._semaphore) { // execution of event is blocked 
       return false; 
      } 
      else { 
       return f(e); 
      } 
     } 
    } 
} 


var handle_storage = BetterStorage.createHandler(function() { 
     alert('storage event'); 
}); 
window.addEventListener("storage", handle_storage, false); 
+1

此解决方案无效 - setItem在事件触发前完成并返回,因此信号量已被清除。 –

相关问题