本文是我重温 js《高级》书后整理的笔记。
所谓事件,就是文档或者浏览器窗口发生的一些特定的交互瞬间。
事件流
定义
页面中接收事件的顺序
类别
- 事件捕获 (Netscape)
- 事件冒泡 (IE)
曾经有个前辈问我,事件捕获和事件冒泡哪个比较重要。
那时候,我答不上来。
答案他没有说。
我现在知道,是事件冒泡。
(下文会给出解释)
事件冒泡
顺序
最具体的元素 ==> 文档(也就是 document)
注意
IE9+、FF、Chrome、Safari 中会一直冒泡到 window 对象
事件捕获
顺序
和冒泡相反。
window ==> 最具体元素
DOM 事件流
DOM 事件流在 DOM2 级事件里规定,并且 IE8- 的浏览器不支持。
阶段
它规定了事件流应该包括三个阶段:
事件捕获 => 处于目标阶段 => 事件冒泡
注意
事件捕获阶段,在元素的父级元素就已经停止。这个阶段中,目标元素不会接收到事件。
处于目标的阶段,通常会视为冒泡的一部分,事件从这个地方开始,往上冒泡传递回文档。
事件处理程序
顾名思义,某个事件发生时响应的一段程序(函数)。
它的制定经过了几个阶段:
- HTML 事件处理程序
- DOM0 级事件处理程序
- DOM2 级事件处理程序
- DOM3 级事件处理程序
(不要问我为什么没有 DOM1)
下面将它简称为 handler。
DOM0 级
把函数赋给 DOM 元素的一个事件属性
执行时机
在冒泡阶段执行。
删除
把该属性的值赋为 null
DOM2 级
可以为一个元素的同一事件添加多个处理程序。
操作
- 添加事件 - addEventListener()
- 删除事件 - removeEventListener()
两个方法的参数一致:
- 事件类型
- 事件处理程序
- 布尔值(是否在捕获阶段处理事件)(一般以及默认都是 false,不使用捕获,使用冒泡)
特点
绑定了多个 handler 时,事件触发它们的执行顺序为先到先执行(队列)
注意
第二个参数为匿名函数的话,如果没有保存其引用,将无法清除该 handler
且 IE8- 的浏览器不支持 DOM2 级事件处理程序,自己有一套机制(下讲)。
p.s.
还记得一开始的问题吗——“事件捕获和事件冒泡哪个重要”。
在 DOM0 级~中,handler 执行时机是在冒泡阶段;
在 DOM2 级~,我们注册 handler 时,默认使用事件冒泡,也就是说,一般我们不用捕获。
综上两点,可以看出,冒泡比捕获重要些。
IE 事件处理程序
上面讲到,IE8- 的浏览器不支持 DOM2 级,但它们自己有一套事件处理机制。
同样,是通过元素的方法来实现绑定。
操作
- 添加事件 - attachEvent()
- 删除事件 - detachEvent()
两个方法都只接受两个参数。
参数 | 形式 |
---|---|
事件类型 | ‘on’ + type |
处理程序 | handler |
特点
- 只在冒泡阶段执行
- handler 的作用域为 window
- 绑定多个 handler 时,执行顺序为后来居上(栈)
事件对象(非IE8-)
就是 event 对象。包含着所有与事件有关的信息。
特别的属性和方法
属性名 | 意义 |
---|---|
currentTarget | 事件注册的元素 |
target | 事件的目标 |
preventDefault() | 只能取消 cancelable 为 true 的事件的默认行为 |
eventPhase | 可以确定事件当前位于事件流的哪个阶段 |
特点
在 handler 可以获得
事件对象(IE8-)
访问方式
使用 DOM0 级方式的话,就通过 window.event 来获得
使用 IE 事件处理程序时,会往 handler 传入 event 参数;但也可以使用 window.event
特别的属性和方法
属性名 | 意义 |
---|---|
srcElement | 等同 DOM 的 target 属性 |
cancelBubble | 设置为 true 就可取消冒泡 |
returnValue | 设置为 false 时等同 preventDefault() |