上一篇文章的评论中,释然提出了一个很有趣的问题,查阅了一些资料,这里分享下。。。

一. 有趣的问题

// example 1
document.onclick = function() {
alert(‘cecilia’);
}
E.on(document, ‘click’, function() {
alert(‘notify’);
});
document.onclick = function() {
alert(‘handler’);
}
E.on(document, ‘click’, function() {
alert(‘jolin’);
});

在各浏览器下的执行情况:
(1) IE6/7/8:handler -> jolin -> notify
(2) FF:handler -> notify -> jolin
(3) webkit, opera:notify -> handler -> jolin
// example 2
E.on(document, ‘click’, function() {
alert(‘notify’);
});
document.onclick = function() {
alert(‘handler’);
}
E.on(document, ‘click’, function() {
alert(‘jolin’);
});

在各浏览器下的执行情况:
(1) IE6/7/8:handler -> jolin -> notify
(2) FF:notify -> handler -> jolin
(3) webkit, opera:notify -> handler -> jolin

二. 发生了什么?

从上面的例子,我们可以观察到:code 1中有两次事件注册,而code 2中只有一次,各浏览器的输出的结果是相同的,只是结果的输出顺序不同,而FF最特殊。。。

三. 相关资料

既然是FF搞特殊化,那么我们先去它老家看看,一阵淫荡的搜索后,发现一点线索

This method replaces the existing click event listener(s) on the element if there are
any...
// 对于已经存在的事件监听程序(通过传统事件注册模式注册的),FF采取的替换操作。

对于这种情况,其他浏览器是如何处理的呢?找到的权威资料不多,仅发现一篇PPK的相关文章中,有寥寥几句提及该问题:

The second registration of a function to onclick overwrites the first one...
// 可以看到这里提及的处理方式是"overwrites",PPK此处并未提及哪些浏览器采用该处理方式,
// 但既然FF使用了"replaces",那么,我们可以认为非FF使用了"overwrites"(MD,好勉强的逻辑,
// 没知识太恐怖了!!!)

现在,问题的关键在于”replaces:”与”overwrites”的区别了,我个人的理解:

(1) replaces只是改变了值,事件注册的顺序没有改变(联想一下我们熟知的节点替换,替换后,节点的位置
有改变吗?);
(2) overwrites相当于重新注册,顺序自然会发生改变(这相当于重新添加一个节点).

四. 后记

整个的分析都基于”断章取义”和”勉强的逻辑”,仅供大家参考,欢迎提供更权威的资料。。。

“传统事件注册模式”译自PPk文章中的”traditional event registration model”.

, ,

Comments

释然 at 2010年05月5日 9:05 上午

强的~

释然 at 2010年05月5日 9:05 上午

感觉着结论靠谱

涵宇 at 2010年05月9日 11:47 下午

嗯,觉得天哥对于”replace”和”overwrites”的理解比较靠谱,强!

Leave a comment!