• 主页

  • 投资

  • IT

    🔥
  • 设计

  • 销售

  • 共299篇

    前端 - Javascript

关闭

返回栏目

关闭

返回前端 - Javascript栏目

105 - 事件绑定 - DOM2 级事件 - 事件捕获与冒泡阶段

作者:

贺及楼

成为作者

更新日期:2025-02-21 19:40:29

事件绑定 - DOM2 级事件 - 事件捕获与冒泡阶段

在前端开发中,JavaScript 的事件机制是一个核心知识点,它允许我们对用户的各种操作(如点击、滚动等)做出响应。其中,DOM2 级事件为我们提供了更强大、更灵活的事件绑定方式,同时也引入了事件捕获与冒泡的概念。下面我们将深入探讨这些内容。

一、DOM2 级事件概述

在早期的 JavaScript 中,事件绑定主要通过内联事件处理程序(如 <button onclick="doSomething()">Click me</button>)和 DOM0 级事件(如 element.onclick = function() {})来实现。然而,这些方式存在一些局限性,比如一个元素只能绑定一个相同类型的事件处理程序。

DOM2 级事件则解决了这些问题,它提供了 addEventListenerremoveEventListener 方法,允许我们为一个元素添加多个相同类型的事件处理程序,并且可以控制事件的触发阶段。

addEventListener 方法

addEventListener 方法的语法如下:

  1. element.addEventListener(event, function, useCapture);
  • event:事件类型,如 clickmouseover 等,注意不要加 on 前缀。
  • function:事件处理函数,当事件触发时执行。
  • useCapture:一个布尔值,用于指定事件是在捕获阶段(true)还是冒泡阶段(false)触发,默认为 false

removeEventListener 方法

removeEventListener 方法用于移除通过 addEventListener 绑定的事件处理程序,语法如下:

  1. element.removeEventListener(event, function, useCapture);

需要注意的是,移除事件处理程序时传入的参数必须与绑定事件时的参数完全一致,否则无法移除。

下面是一个简单的例子:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. </head>
  6. <body>
  7. <button id="myButton">Click me</button>
  8. <script>
  9. const button = document.getElementById('myButton');
  10. const clickHandler = function () {
  11. console.log('Button clicked!');
  12. };
  13. button.addEventListener('click', clickHandler);
  14. // 移除事件处理程序
  15. // button.removeEventListener('click', clickHandler);
  16. </script>
  17. </body>
  18. </html>

二、事件捕获与冒泡阶段

当一个事件发生时,它会经历三个阶段:捕获阶段、目标阶段和冒泡阶段。

1. 捕获阶段

捕获阶段从文档的根节点(document)开始,依次向下查找触发事件的目标元素。在这个过程中,如果某个元素绑定了在捕获阶段触发的事件处理程序,那么该处理程序会被执行。

2. 目标阶段

当事件到达触发事件的目标元素时,进入目标阶段。此时,无论事件处理程序是在捕获阶段还是冒泡阶段绑定的,都会被执行。

3. 冒泡阶段

冒泡阶段与捕获阶段相反,它从目标元素开始,依次向上将事件传播到文档的根节点。在这个过程中,如果某个元素绑定了在冒泡阶段触发的事件处理程序,那么该处理程序会被执行。

下面是一个具体的例子来演示事件捕获与冒泡:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. </head>
  6. <body>
  7. <div id="outer">
  8. <div id="inner">Click me</div>
  9. </div>
  10. <script>
  11. const outer = document.getElementById('outer');
  12. const inner = document.getElementById('inner');
  13. // 捕获阶段
  14. outer.addEventListener('click', function () {
  15. console.log('Outer div - Capture phase');
  16. }, true);
  17. inner.addEventListener('click', function () {
  18. console.log('Inner div - Capture phase');
  19. }, true);
  20. // 冒泡阶段
  21. outer.addEventListener('click', function () {
  22. console.log('Outer div - Bubble phase');
  23. }, false);
  24. inner.addEventListener('click', function () {
  25. console.log('Inner div - Bubble phase');
  26. }, false);
  27. </script>
  28. </body>
  29. </html>

当我们点击 inner 元素时,控制台会依次输出:

  1. Outer div - Capture phase
  2. Inner div - Capture phase
  3. Inner div - Bubble phase
  4. Outer div - Bubble phase

事件捕获与冒泡的应用场景

  • 事件捕获:通常用于在事件到达目标元素之前进行一些预处理,例如全局的事件拦截。
  • 事件冒泡:常用于事件委托,即把事件处理程序绑定到父元素上,利用事件冒泡的特性,当子元素触发事件时,事件会冒泡到父元素,从而减少事件处理程序的绑定数量,提高性能。

下面是一个事件委托的例子:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. </head>
  6. <body>
  7. <ul id="myList">
  8. <li>Item 1</li>
  9. <li>Item 2</li>
  10. <li>Item 3</li>
  11. </ul>
  12. <script>
  13. const list = document.getElementById('myList');
  14. list.addEventListener('click', function (event) {
  15. if (event.target.tagName === 'LI') {
  16. console.log('Clicked on: ' + event.target.textContent);
  17. }
  18. });
  19. </script>
  20. </body>
  21. </html>

在这个例子中,我们只需要给 ul 元素绑定一个事件处理程序,当点击任意一个 li 元素时,事件会冒泡到 ul 元素,从而触发事件处理程序。

三、总结

事件绑定方式 特点 示例
DOM0 级事件 简单,但一个元素只能绑定一个相同类型的事件处理程序 element.onclick = function() {}
DOM2 级事件 允许为一个元素添加多个相同类型的事件处理程序,可控制事件触发阶段 element.addEventListener('click', function, false)
事件阶段 方向 应用场景
捕获阶段 从文档根节点到目标元素 全局事件拦截、预处理
冒泡阶段 从目标元素到文档根节点 事件委托,减少事件处理程序绑定数量

通过掌握 DOM2 级事件和事件捕获与冒泡的概念,我们可以更加灵活地处理各种用户事件,提高代码的可维护性和性能。