JavaScript 事件机制详解

65 阅读3分钟

JavaScript 事件机制详解

JavaScript 事件机制是前端交互的核心,它负责处理用户操作(如点击、输入等)并触发相应的逻辑。本文将结合实例代码,详细解析事件的传播机制、监听方式及事件委托的应用。

一、事件的传播阶段

在 DOM 树中,事件的传播分为三个阶段,如同水滴落入水面的扩散与汇聚过程:

  1. 捕获阶段(Capture Phase) :事件从最顶层的 document 开始,逐层向下传播到目标元素的父级(由外到内)。
  2. 目标阶段(Target Phase) :事件到达实际触发的目标元素。
  3. 冒泡阶段(Bubble Phase) :事件从目标元素逐层向上传播回 document(由内到外)。

image.png 示意图说明:捕获阶段从 document 向下到目标元素,冒泡阶段从目标元素向上返回 document

二、事件监听方式

1. DOM 0 级事件(不推荐)

直接在 HTML 标签或 DOM 元素上绑定事件,缺点是模块化差,无法绑定多个同类型事件。

<!-- HTML内直接绑定 -->
<body onclick="alert('橙子')">

2. DOM 2 级事件(推荐)

使用 addEventListener 方法,支持在不同阶段监听事件,且可绑定多个同类型事件。

语法:

element.addEventListener(eventType, callback, useCapture);
  • useCapture:布尔值,true 表示在捕获阶段执行,false(默认)表示在冒泡阶段执行。

三、事件传播示例

以下代码演示了父子元素的事件传播机制:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <style>
  #parent { 
    width: 200px; 
    height: 200px; 
    background: red; }
  #child { 
    width: 100px; 
    height: 100px; 
    background: blue; }
  </style>
</head>
<body>
  <div id="parent">
    <div id="child"></div>
  </div>

  <script>
    // 父元素在冒泡阶段监听(默认false)
    document.getElementById('parent').addEventListener('click', () => {
      console.log('parent click');
    }, false);

    // 子元素在冒泡阶段监听,并阻止冒泡
    document.getElementById('child').addEventListener('click', (event) => {
      event.stopPropagation(); // 阻止事件继续冒泡
      console.log('child click');
    }, false);
  </script>
</body>
</html>

执行结果:点击蓝色子元素时,仅输出 child click(因 stopPropagation 阻止了事件冒泡到父元素);点击红色父元素(非子元素区域)时,输出 parent click

四、事件委托

当需要为多个同类型子元素绑定事件时,直接循环绑定会导致内存开销过大。事件委托利用事件冒泡特性,将事件监听绑定到父元素,通过 event.target 判断实际触发元素。

示例代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>事件委托</title>
</head>
<body>
  <ul id="list">
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>

  <script>
    // 事件委托:监听父元素ul,处理子元素li的点击
    document.getElementById('list').addEventListener('click', (event) => {
      // event.target 指向实际点击的li元素
      console.log('点击了:', event.target.innerHTML);
    });
  </script>
</body>
</html>

优势

  1. 减少事件监听数量,降低内存消耗;
  2. 动态新增的子元素(如通过 JS 添加的 li)自动继承事件处理,无需重新绑定。

五、核心总结

  1. 事件传播遵循「捕获→目标→冒泡」三阶段;
  2. addEventListener 的 useCapture 参数控制监听阶段;
  3. event.stopPropagation() 可阻止事件继续传播;
  4. 事件委托通过父元素代理子元素事件,优化性能并支持动态元素。

掌握事件机制是实现复杂交互的基础,合理运用事件委托能显著提升代码效率。