Javascript事件模型:捕获和冒泡

在Javascript中用户交互的核心部分就是事件处理。本文为对事件模型和处理机制的总体性描述。

Event是什么?

event是用户操作网页时发生的交互动作,比如click/move, event除了用户触发的动作外,还可以是文档加载,窗口滚动和大小调整。


Event模型是什么?

Event模型指的是浏览器如何处理发生的事件。不同的浏览器其处理机制也不尽相同,甚至截然相反。

一般而言,某个界面元素发生单个事件,那么事件的处理对象就是该界面元素。

但一个典型的问题是如果该界面元素存在父子元素,而且父子元素也定义了同样的事件,

这个时候事件该如何处理呢,事件在父子元素之间是如何传递的呢,谁会先接收到这个事件,又是谁先处理呢?

举个例子:

-----------------------------------
| element1                        |
|   -------------------------     |
|   |element2               |     |
|   -------------------------     |
|                                 |
-----------------------------------
element2是element1的子元素,两者都定义了onclick事件。

这就是事件模型(事件序列)要解决的问题。


两种模型

回到网景和微软斗争的年代,两个公司选择了不同的道路:

网景选择的是事件捕获(event capturing)模型,即网景认为element1首先获取到事件;

微软选择了和其桌面系统类似的消息机制,认为element2有更高的优先权,即事件冒泡(event bubbling),

这两个模型截然相反,IE仅支持event bubbling. Mozilla, Opera 7等两种都支持. 更老版本的Opera和iCab两种都不支持。

你现在也许体会到了什么是互联网最初那最好也最坏的年代。


事件捕获
                   | |
--------------- | |-----------------
| element1      | |                |
|   -----------    | |-----------     |
|   |element2   \ /          |     |
|   -------------------------     |
|        Event CAPTURING          |
-----------------------------------
看上面箭头的方向,element1的事件处理器首先被触发,然后向下传递到element2

事件冒泡

                 / \
--------------| |-----------------
| element1   | |                |
|   ----------- | |-----------     |
|   |element2 | |          |     |
|   -------------------------     |
|        Event BUBBLING           |
-----------------------------------
与事件捕获相反,element2的事件处理器会首先被触发。


W3C模型

W3C非常理智的处理了这种差异,在两者之间采取了中和的方法,W3C模型规定任何事件首先会被捕获直到遇到目标元素,然后再向上返回。

                     | |  / \
-----------------| |--| |-----------------
| element1       | |  | |                |
|   ---------------| |--| |-----------     |
|   |element2    \ /   | |          |     |
|   --------------------------------     |
|        W3C event model                 |
------------------------------------------

WEB开发人员可以通过addEventListener()方法来选择在哪个阶段注册事件处理器(捕获阶段还是冒泡阶段),这个方法在Advanced models中有详细描述,其最后一个参数为true,则代表事件在捕获阶段被处理,false则代表事件在冒泡阶段被处理。


比如:

element1.addEventListener('click',doSomething2,true)
element2.addEventListener('click',doSomething,false)
事件首先被element1捕获,然后执行doSomething2,接着事件传递给element2,doSomething被执行,接着,事件冒泡回溯,检查是否有父元素(element1)定义了冒泡阶段的事件处理器,这里没有,所以事件终止。


兼容传统模型

在支持W3C DOM的浏览器中,传统的事件注册被看作是注册于冒泡阶段。

element1.onclick = doSomething2;


by iefreer


参考资料:

http://www.w3.org/wiki/Handling_events_with_JavaScript

http://www.quirksmode.org/js/events_order.html
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值