我可以成功绑定事件以更改为localStorage(使用jquery):
$(window).bind('storage', function(e)
{
alert('change');
});
localStorage.setItem('someItem', 'someValue');
如果我使用sessionStorage,则不会触发事件:
$(window).bind('storage', function(e)
{
alert('change');
});
sessionStorage.setItem('someItem', 'someValue');
为什么会这样?
答案 0 :(得分:20)
每个标签都会隔离sessionStorage
,因此无法进行通信。 sessionStorage
的事件仅在同一选项卡上的帧之间触发。
修改强>
我做了以下例子:
http://codepen.io/surdu/pen/QGZGLO?editors=1010
示例页面有两个按钮,用于触发本地存储和会话存储更改。
它还将iframe嵌入到另一个侦听存储事件更改的codepen中:
http://codepen.io/surdu/pen/GNYNrW?editors=1010 (您应该在另一个标签中打开它。)
您会注意到当您按下“写本地”按钮时,在iframe和打开的选项卡中都会捕获事件,但是当您按下“会话写入”时,只有嵌入式iframe会捕获该事件。
答案 1 :(得分:14)
这就是我认为的方式。从spec(强调添加):
在a上调用
setItem()
,removeItem()
和clear()
方法时Storage
对象x与会话存储区域相关联,如果 方法做了一些事情,然后在每个Window对象的Window中 object的sessionStorage属性的Storage对象与之关联 相同的存储区域除x 之外,必须触发存储事件
我认为这意味着事件将在共享会话存储对象的任何其他文档中被触发,而不是导致事件触发的文档。
<强>更新强>
这是另一个very similar question,它似乎与我上面提到的内容一致(答案引用了规范中的相同段落)。
答案 2 :(得分:3)
这个问题似乎得到了不少观点,所以我只是将其作为额外信息发布。
如果您想要专门响应sessionStorage对象的更新,您可以忽略localStorage引起的事件:
$(window).on('storage',function(e){
if(e.originalEvent.storageArea===sessionStorage){
alert('change');
}
// else, event is caused by an update to localStorage, ignore it
});
我讨厌jQuery,所以也会发布原生版本:
window.addEventListener('storage',function(e){
if(e.storageArea===sessionStorage){
alert('change');
}
// else, event is caused by an update to localStorage, ignore it
});