事件 event 是用户操作网页时,产生的交互行为或者网页本身的一些操作。现代浏览器一般有三种事件模型。
事件模型
1. 原始事件模型(DOM0级)
事件发生后,没有传播的概念,没有事件流。监听函数只是元素的一个属性值:
<!-- 1. 直接在元素的值绑定 --><button onclick="click()"></button><!-- 2. 通过js绑定 --><script>document.querySelector('button').onclick = function () {}</script>
优点:
- 兼容所有浏览器
缺点:
事件流有两个阶段:
- 事件处理阶段:事件达到目标元素时,触发监听事件
- 事件冒泡阶段:事件从目标元素冒泡到document,并且一次检查是否有监听函数,有则执行。
示例:
// 绑定事件el.attachEvent(eventType, handler)// 移除事件el.detachEvent(eventType, handler)
3. DOM2事件模型
新增冒泡、捕获的概念,并支持一个元素节点绑定多个监听事件。
事件捕获和事件冒泡(capture、bubble)
事件捕获与事件冒泡示意图
事件流分为三个阶段:
- 事件捕获阶段(1、2、3):事件从 document 向下传播到目标元素,依次检查节点的事件绑定并执行。
- 事件处理阶段(4):事件到达目标元素,触发监听事件
- 事件冒泡阶段(5、6、7):事件从目标元素向上冒泡至 document,依次检查节点的事件绑定并执行。
事件监听(addEventListener)
addEventListener 有三个参数:
- 事件名
- 回调函数
- 执行阶段:为
true则事件在捕获阶段执行,为false则在冒泡阶段执行。 ```javascript /**- addEventListener有三个参数 事件名称、事件回调、捕获/冒泡
- 设置为true,则事件在捕获阶段执行,为false则在冒泡阶段执行。 */
btn.addEventListener(‘click’, function() { console.log(‘btn’) }, true)
box.addEventListener(‘click’, function() { console.log(‘box’) }, false) ```
事件传播
当 事件 发生在 DOM 元素上时,该事件并不完全发生在那个元素上。
即 DOM2事件模型 中的 事件捕获、处理、冒泡阶段。
事件委托(代理)
事件委托(代理)本质上利用了 事件冒泡 的机制。
事件在冒泡过程中,会上升至其父元素。
且父元素可以通过事件对象 event.target 获取到触发事件的目标节点。
因此可以将监听事件绑定在父元素,通过事件获取到子元素。
例如监听100个 <li> 的点击事件时,将事件直接绑定在其父元素 <ul> 上。
事件委托的优点:
- 降低内存消耗,无需为每个子元素都绑定监听事件
- 方便动态绑定事件。子元素动态增减无需单独再绑定事件。
事件捕获与事件冒泡示意图