继this question之后,我在将一个函数绑定到Chrome 8.0.552.224中的Storage对象的change事件时得到了一个奇怪的结果。
测试:
<!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>
当我这样做时,我会在第二个选项卡和第二个窗口上显示一个警告框,但不会在调用该事件的选项卡上显示(我点击了)。据我所知,我应该看到三个警告框(每个标签打开一个)。
这是一个错误吗?有其他人得到这种行为吗?如果不是你在运行什么版本?或者我是否完全错了?
答案 0 :(得分:42)
事实证明,规范实际上表示这是理想的行为,因此IE9的实施已被破坏。
4.2 sessionStorage属性
当在Storage对象 x 上调用setItem(),removeItem()和clear()方法时...如果方法做了什么,那么在每个HTMLDocument中...... [是]与相同的存储区域相关联,除x 之外,必须触发存储事件....
正如我们所看到的,规范确实做得很清楚,这是指定的行为。这就是Opera 10的实施被破坏的原因,也很可能也是IE9实施被破坏的原因。
我们从中学到了什么?请务必阅读每个,单个,规范中的字词(特别是如果您正在实施这些内容......)。
正如你所说,这里的基本行为是“调用当前页面以外的所有页面”。
从去年7月开始有一个旧的Chrome Bug Report。
正如人们可以阅读的那样,Firefox也有同样的“问题”。我用最新的夜间测试了这个,但仍然像Chrome一样。
Opera 11中的另一个测试表明,这必须是某种特定的行为,因为Opera 11完全相同,但Opera 10 在所有窗口/标签上发布了触发事件。可悲的是,Opera 11的官方更改日志并未说明此行为的任何更改。
通过specification阅读,没有任何内容表明这种行为。我唯一能找到的是:
存储区域发生变化时会触发存储事件,如前两节(会话存储,本地存储)中所述。
当发生这种情况时,用户代理必须将任务排队,以使用名称存储来触发事件,该事件不会冒泡且不可取消,并且在Document对象具有Storage对象的每个Window对象上使用StorageEvent接口那是受影响的。
注意:这包括未完全处于活动状态的Document对象,但事件循环会忽略对其触发的事件,直到Document再次完全处于活动状态。
嗯,这意味着什么?
来自另一个specification:
当文档是浏览上下文的活动文档时,它被认为是完全活动的,并且其浏览上下文是顶级浏览上下文,或嵌套浏览上下文的文档本身是完全活动的。
没有意义吗?是。它以任何方式帮助我们吗?没有。
所以我们(在JavaScript聊天室中)在#whatwg上查看了所有这些内容,到目前为止还没有响应。我们会在得到任何回复后立即更新我的答案。
暂时结束
Firefox,Chrome,Safari和Opera具有完全相同的行为。也就是说,它们不会触发有机会进入localStorage的选项卡/窗口。
但IE9 Beta的行为与Opera 10类似,因此它会在所有标签/窗口上触发。
由于localStorage规范的作者在R&amp; D谷歌工作,我几乎不怀疑Chrome会出错。而且由于在Bugzilla和Opera上没有错误,因此改变了11中的行为,似乎这是它应该工作的方式。仍然没有回答为什么它以这种方式工作以及为什么IE9表现不同,但我们仍在等待来自#whatwg的响应。
答案 1 :(得分:1)
Ivo Wetzel对出现问题的答案是正确的。
我遇到了同样的问题,但通过在启动存储更改的选项卡中手动创建并触发StorageEvent,设法在规范中解决此限制(请参阅StorageEvent#initStorageEvent)。