事件模型
一、监听函数
js 有三种方法,可以为事件绑定监听函数
- HTML 的 on- 属性
- 元素节点的事件属性,也可以指定监听函数
EventTarget.addEventListener()
DOM 节点实例的方法,有三个参数,分别事件类型、回调函数和表示是否在捕获阶段触发的布尔值
上面三种方法,第一种违反了 HTML 和 JavaScript 相分离原则,不推荐。第二种方法,如果多次定义了同个属性,后者会覆盖前者,不推荐。
第三种方法有点:
- 同一事件可以添加多个监听函数
- 能够指定在哪个阶段(捕获阶段还是冒泡阶段)触发监听函数
- 除了 DOM 节点,其他对象(如
window
,XMLHttpRequest
等)也有这个接口,它等于是整个 JavaScript 统一的监听函数接口。
二、this 指向
监听函数内部的this
指向触发事件的那个元素节点。
<button id="btn" onclick="console.log(this.id)">点击</button>
// btn
复制代码
三、事件的传播
一个事件发生后,会在子元素和父元素之间传播,分为三个阶段:
- 第一阶段:从
window
对象传导到目标节点(上层传到底层),称为“捕获阶段”(capture phase) - 第二阶段:在目标节点上触发,称为“目标阶段”(target phase)
- 第三阶段:从目标节点传导回
window
对象(从底层传回上层),称为“冒泡阶段”(bubbling phase)
四、事件代理
由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理(delegation)。
阻止事件冒泡使用event.stopPropagation
Event 对象
事件发生以后,会产生一个事件对象,作为参数传给监听函数。
一、实例属性
-
Event.bubbles
返回布尔值,表示当前事件是否会冒泡 -
Event.eventPhase
返回一个整数常量,表示事件目前所处阶段- 0,事件目前没有发生。
- 1,事件目前处于捕获阶段,即处于从祖先节点向目标节点的传播过程中。
- 2,事件到达目标节点,即
Event.target
属性指向的那个节点。 - 3,事件处于冒泡阶段,即处于从目标节点向祖先节点的反向传播过程中。
-
Event.cancelable
返回布尔值,表示事件可否取消。属性只读 -
Event.preventDefault
当上面的值为true
时可以调用,用来取消事件。 -
Event.cancelBubble
属性是一个布尔值,如果设为true
,相当于执行Event.stopPropagation()
,可以阻止事件的传播。 -
Event.currentTarget
返回事件当前所在的节点,即正在执行监听函数所绑定的节点。Event.target
返回原始触发事件的那个节点。 -
Event.type
返回一个表示事件类型的字符串 -
Event.timeStamp
返回一个毫秒时间戳,表示事件发生的时间。 -
Event.isTrusted
返回一个布尔值,表示事件是否由真实的用户行为产生。 -
Event.detail
属性只有浏览器的 UI 事件才具有,返回一个数值,表示事件的某种信息。
二、实例方法
Event.preventDefault()
取消浏览器对当前事件的默认行为。Event.stopPropagation()
阻止事件冒泡Event.stopImmediatePropagetion
阻止同一个事件的其他监听函数被调用,不管监听函数定义在当前节点还是其他节点。也就是说,该方法阻止事件的传播,比Event.stopPropagation()
更彻底。Event.composedPath()
返回一个数组,成员是事件的最底层节点和依次冒泡经过的所有上层节点。