事件是一种异步编程的实现方式
1.EventTarget 接口
DOM 的事件操作(监听和触发), 都定义在 EventTarget 接口,Element 节点、docuemnt 节点、window 、XMLHttpRequest、AudioNode、AudioContext,都部署了这个接口
定义了三个方法
- addEventListener: 绑定事件的监听函数
- removeEventListener: 解除绑定的监听函数
- dispatchEvent: 触发事件
2. 事件的传播
当一个事件发生后,它会在不同的DOM节点之间传播,事件传播分为三个阶段
-
第一阶段:从window对象传导到目标节点,称为”捕获阶段“(captrue phase)
-
第二阶段:从目标节点上触发,称为”目标阶段“(target phase)
-
第三阶段:从目标节点传导回window对象,称为”冒泡阶段“(bubbling phase)
下面给这两个元素节点都设置监听函数,点击p 标签后
var div = docuemnt.getElementById('div')
var p = docuemnt.getElementById('p')
div.addEventListener('click', callback, true)
p.addEventListener('click', callback, true)
div.addEventListener('click', callback, false)
p.addEventListener('click', callback, true)
function callback(e) {
console.log( 'tag:' + e.currentTarget.tagName, 'EventPhase:' + event.eventPhase)
}
上面代码表示,click事件被触发了四次:
节点的捕获阶段和冒泡阶段各1次,
- 捕获阶段:事件从向
传播时,触发
的click事件; - 目标阶段:事件从到达
时,触发
的click事件;
- 目标阶段:事件离开
时,触发
的click事件;
- 冒泡阶段:事件从
传回
时,再次触发的click事件。
3. 事件的代理
由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理(delegation)
4.Event 对象
事件发生之后,会产生一个事件对象,作为参数传递给监听函数,浏览器提供了一个 Event 对象,所有的事件都是这个对象的实例
var event = new Event(typeName, eventInit)
Event构造函数接收两个参数,第一个参数是事件名称,第二个参数是一个对象,表示元素的配置,eventIint有两个属性
-
bubbles: Boolean, 默认是false,表示是否冒泡
-
cancelable: Boolean, 默认是false, 表示事件是否可以被取消
var eat = new Event('eat', { bubbles: true, cancalable: false }) document.addEventListener('eat', callback, false) document.dispatchEvent(eat)