一、事件与事件流
事件:在JavaScript中,事件是指用户在浏览器中执行的某个动作或者浏览器自身发生的某个变化。常见的事件类型包括点击事件、鼠标移动事件、键盘事件等。每个事件都有一个相关的事件对象,其中包含了关于事件的详细信息,例如事件的类型、触发该事件的元素等。
事件流:是指在DOM结构中发生的事件传播过程。
二、事件模型
(1)DOM0级事件模型
- 该模型不会传播,没有事件流的概念
- 兼容所有的浏览器
- 直接在DOM对象上注册事件名称
(2)DOM2级事件模型
- 事件捕获阶段:事件从
document一直向下传播到目标元素, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行 - 事件处理阶段:事件到达目标元素, 触发目标元素的监听函数
- 事件冒泡阶段:事件从目标元素冒泡到
document, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行
(2)IE事件模型(用的很少)
- 事件处理阶段:首先执行目标元素绑定的监听事件
- 事件冒泡阶段:事件从目标元素冒泡到
document, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行
三、事件委托(事件代理)
事件委托本质上是利用了浏览器事件冒泡的机制。 因为事件在冒泡过程中会上传到父节点,父节点可以通过事件对象获取到目标节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件,这种方式称为事件委托(事件代理)。
(1)事件委托的基本步骤
- 选择一个合适的父元素作为事件的监听器。通常选择父元素是因为它包含了我们想要处理事件的子元素。
- 在父元素上绑定事件监听器,监听我们感兴趣的事件(例如点击事件)。
- 当事件发生时,事件会冒泡到父元素。
- 在父元素上的事件监听器中,通过检查事件对象的
event.target属性,确定事件的真正目标元素。 - 基于目标元素的特征、类名、标签名等,执行相应的操作或调用对应的事件处理函数。
(2)事件委托的优点
可以大量节省内存占用,减少事件注册
<ul id="list">
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
如上面代码所示,如果给每个li列表项都绑定一个函数,那对内存的消耗是非常大的,因此较好的解决办法就是将li元素的点击事件绑定到它的父元素ul身上,执行事件的时候再去匹配判断目标元素。
动态元素处理
当页面上存在大量动态生成的元素时,通过事件委托,只需要在它们的共同父元素上绑定一个事件监听器,而不需要为每个元素单独绑定监听器。