事件

事件是某事发生的信号。所有的 DOM 节点都生成这样的信号(但事件不仅限于 DOM)。比如:当鼠标点击一个元素时,会触发 click 事件。以下代码就是在用户点击按钮后弹出「Click!」消息。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
  </head>
  <body>
    <button id="button">Click Me</button>
    <script>
      button.onclick = () => {
        alert("Click!");
      };
    </script>
  </body>
</html>

捕获与冒泡

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
  </head>
  <body>
    <div onclick="alert('The handler!')">
      <em
        >If you click on <code>EM</code>, the handler on
        <code>DIV</code> runs.</em
      >
    </div>
  </body>
</html>

运行上面的代码,你会发现点击「EM」时仍然能触发对话框,这是因为点击 <em> 时会触发 <div> 上的事件。从内到外运行事件程序叫做「冒泡」(bubbling)。以下是冒泡的示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
  </head>
  <body>
  <style>
      body * {
          margin: 10px;
          border: 1px solid blue;
      }
  </style>

  <form onclick="alert('form')">FORM
    <div onclick="alert('div')">DIV
      <p onclick="alert('p')">P</p>
    </div>
  </form>
  </body>
</html>

事件处理的另一个阶段叫「捕获」(capturing),它是从外到内执行事件处理程序,和冒泡相反。

DOM 事件标准规定了事件传播的顺序:

  1. 捕获阶段(Capturing phase)—— 事件(从 Window)向下走近元素。
  2. 目标阶段(Target phase)—— 事件到达目标元素。
  3. 冒泡阶段(Bubbling phase)—— 事件从元素上开始冒泡。

同一事件,先捕获还是先冒泡

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
  </head>
  <body>
    <button id="button">button</button>
  </body>
  <script>
    button.addEventListener("click", () => console.log("bubbling"));
    button.addEventListener("click", () => console.log("capturing"), true);
  </script>
</html>

以上代码在 Firefox 允许会按代码顺序打印,先打印「bubbling」,再打印「capturing」。在 Chrome>89 则按先捕获的顺序,也就是先打印「capturing」,再打印「bubbling」。

参考资料

https://zh.javascript.info/bubbling-and-capturing