程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • HTML

  • CSS

  • JavaScript

    • 简介和用法
    • 变量和数据类型
    • 运算符
    • 数据类型转换
    • 选择结构
    • 循环结构
    • 数组
    • 数组遍历
    • 函数
    • Debug调试
    • DOM
    • 事件处理
      • 1. 简介
      • 2. 绑定事件
        • 2.1 静态绑定
        • 2.2 动态绑定(直接赋值)
        • 2.3 动态绑定(事件监听)
        • 2.4 事件对象
        • 2.5 this 关键字
      • 3. 常用事件
        • 3.1 鼠标事件
        • 3.2 键盘事件
        • 3.3 表单事件
        • 3.4 表单元素的方法
        • 3.5 复选框的全选案例
        • 3.6 事件绑定方式
        • 1. 绑定全局事件(window 对象)
        • 2. 绑定特定元素的事件
      • 4. 事件操作
        • 4.1 事件流
        • 4.2 事件冒泡/事件捕获
        • 4.2.1 事件冒泡示例
        • 4.2.2 事件捕获示例
        • 4.2.3 阻止事件冒泡示例
        • 4.3 事件代理/事件委托
        • 4.4 事件默认行为
      • 5. 综合示例
    • BOM(浏览器对象模型)
    • 自定义对象
    • 原型 (Prototype)
    • 内置对象
    • 客户端存储
    • 模块加载方案
  • 前端三剑客
  • JavaScript
scholar
2024-07-19
目录

事件处理

# 事件处理

# 1. 简介

事件:发生在HTML元素上的事情,可以是用户的行为,也可以是浏览器的行为,例如:

  • 用户点击了某个HTML元素
  • 用户将鼠标移动到某个HTML元素上
  • 用户输入数据时光标离开
  • 页面加载完成

事件源:事件触发的源头,即触发事件的元素,如按钮、输入框、超链接等。

事件对象:当一个事件发生时,这个事件相关的详细信息会被保存到一个对象中,称为event对象。

事件监听:监听事件的发生,绑定事件函数,当事件被触发后执行该事件函数,即回调函数。

# 2. 绑定事件

在JavaScript中,可以通过多种方式为DOM元素绑定事件。以下是常见的三种方式:

# 2.1 静态绑定

静态绑定是直接在HTML标签中定义事件处理函数。这种方式简单直观,但不适用于需要动态变化的事件绑定。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>静态绑定示例</title>
    <script type="text/javascript">
        // 定义事件处理函数,接收事件源元素作为参数
        function fn(element) {
            console.log("静态绑定,事件源:", element); // 输出事件源元素
        }

        // 定义事件处理函数,不接收参数
        function fnWithoutThis() {
            console.log("静态绑定,this:", this); // 输出 this 的值
        }
    </script>
</head>
<body>
    <!-- 通过onclick属性静态绑定事件处理函数,传递事件源元素 -->
    <input type="button" value="按钮(传递 this)" onclick="fn(this)">
    
    <!-- 通过onclick属性静态绑定事件处理函数,不传递事件源元素 -->
    <input type="button" value="按钮(不传递 this)" onclick="fnWithoutThis()">
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

注意

  • 在静态事件绑定中将 this 作为参数传递给事件处理函数时,this 表示事件源元素。
  • 如果不传递 this直接使用,那么在非严格模式下,this 指向全局对象 window;在严格模式下,this 的值是 undefined。

# 2.2 动态绑定(直接赋值)

动态绑定是通过JavaScript代码为DOM对象的事件属性赋值。这种方式适合需要在页面加载后动态设置或更改事件处理函数。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>动态绑定示例</title>
</head>
<body>
    <input type="button" value="按钮" id="btn">
    <script type="text/javascript">
        // 获取DOM对象
        var btn = document.getElementById("btn");
        // 通过直接赋值的方式绑定事件处理函数
        btn.onclick = function() {
            console.log("动态绑定");
        };
    </script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 2.3 动态绑定(事件监听)

使用 addEventListener 方法为DOM对象绑定事件监听器。这种方式更为灵活,允许为同一事件绑定多个处理函数,不会覆盖已有的事件处理函数。

addEventListener 方法的第一个参数是事件类型(事件名称),第二个参数是回调函数(事件处理函数)。

element.addEventListener(event, callback, useCapture);
1
  • event:字符串,表示事件的类型,例如 "click", "mouseover", "keydown" 等。
  • callback:函数,当指定类型的事件触发时,将调用这个回调函数。
  • useCapture:可选参数,布尔值,表示事件是否在捕获阶段执行。默认值为 false,表示事件在冒泡阶段执行。

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件监听示例</title>
</head>
<body>
    <!-- 创建一个按钮 -->
    <input type="button" value="按钮" id="btn">
    <script type="text/javascript">
        // 获取DOM对象,即按钮元素
        var btn = document.getElementById("btn");
        
        // 通过addEventListener方法绑定事件监听器
        // 第一个参数是事件类型 "click"
        // 第二个参数是回调函数,当按钮被点击时执行
        btn.addEventListener('click', function() {
            console.log("动态绑定的点击事件被触发");
        });

        // 绑定另一个事件监听器到同一个事件类型
        // 当按钮被点击时,除了上面的回调函数外,还会执行这个回调函数
        btn.addEventListener('click', function() {
            alert("按钮被点击了!");
        });
    </script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

在这个示例中,使用 addEventListener 方法为按钮元素绑定了两个点击事件监听器。第一个监听器在按钮被点击时向控制台输出消息,第二个监听器在按钮被点击时显示一个弹出框。两个事件监听器都绑定到了同一个事件类型 "click" 上,不会相互覆盖。

注意

在动态绑定(事件监听)中,无论是否传递 this,在事件回调函数中直接使用 this 都代表事件源(即触发事件的元素)

# 2.4 事件对象

事件对象 event 提供了关于事件的详细信息。在事件处理函数中,可以通过第一个参数访问事件对象。无论是通过 addEventListener 动态绑定事件,还是通过 HTML 属性(如 onclick)静态绑定事件,事件处理函数的第一个参数都是事件对象。

注意: 使用事件对象时,必须在事件处理函数的第一个参数传入一个形参,这个形参就是事件对象。

常见的事件对象属性包括:

  • target:事件的目标元素,即事件源。
  • type:事件的类型。
  • timeStamp:事件生成的日期和时间。
  • clientX:当事件被触发时,鼠标指针的水平坐标。
  • clientY:当事件被触发时,鼠标指针的垂直坐标。

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件对象示例</title>
</head>
<body>
    <input type="button" value="按钮" id="btn">
    <script type="text/javascript">
        // 获取DOM对象
        var btn = document.getElementById("btn");
        // 绑定事件监听器,传入事件对象
        btn.addEventListener('click', function(event) {
            console.log("事件类型:", event.type); // 输出事件类型
            console.log("事件目标:", event.target); // 输出事件源 event.target = this
            console.log("鼠标坐标:", event.clientX, event.clientY); // 输出鼠标点击位置的坐标
        });
    </script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 2.5 this 关键字

在事件回调函数中,this 关键字表示事件源,即触发事件的元素。以下示例展示了 this 的用法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>this关键字示例</title>
</head>
<body>
    <input type="button" value="按钮" id="btn">
    <script type="text/javascript">
        // 获取DOM对象
        var btn = document.getElementById("btn");
        // 绑定事件监听器
        btn.addEventListener('click', function() {
            console.log("事件源:", this); // 输出事件源元素
        });
    </script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 3. 常用事件

所有的事件属性既可以绑定在 window 对象上,也可以绑定在具体的 DOM 元素上。主要的区别在于作用范围和使用场景不同。

# 3.1 鼠标事件

鼠标事件在用户与网页元素进行交互时触发,常用的鼠标事件如下:

事件名 描述
onclick 鼠标单击
ondblclick 鼠标双击
onmouseover 鼠标移到某元素之上
onmouseout 鼠标从某元素上移开
onmousedown 鼠标按钮被按下
onmouseup 鼠标按键被松开
onmousemove 鼠标被移动
oncontextmenu 鼠标右键单击

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>鼠标事件示例</title>
    <script>
        function handleClick() {
            console.log("鼠标单击");
        }
        function handleDblClick() {
            console.log("鼠标双击");
        }
        function handleMouseOver() {
            console.log("鼠标移到元素上");
        }
        function handleMouseOut() {
            console.log("鼠标从元素上移开");
        }
    </script>
</head>
<body>
    <button onclick="handleClick()">单击</button>
    <button ondblclick="handleDblClick()">双击</button>
    <div onmouseover="handleMouseOver()" onmouseout="handleMouseOut()">
        鼠标悬停
    </div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 3.2 键盘事件

键盘事件在用户与键盘进行交互时触发,常用的键盘事件如下:

事件名 描述
onkeydown 某个键盘的键被按下去
onkeypress 某个键盘的键被按下去且松开
onkeyup 某个键盘的键被松开

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>键盘事件示例</title>
    <script>
        function handleKeyDown(event) {
            console.log("键被按下: " + event.key);
        }
        function handleKeyPress(event) {
            console.log("键被按下且松开: " + event.key);
        }
        function handleKeyUp(event) {
            console.log("键被松开: " + event.key);
        }
    </script>
</head>
<body>
    <input type="text" onkeydown="handleKeyDown(event)" onkeypress="handleKeyPress(event)" onkeyup="handleKeyUp(event)">
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 3.3 表单事件

表单事件在用户与表单元素进行交互时触发,常用的表单事件如下:

事件名 描述
onfocus 元素获得焦点
onblur 元素失去焦点
onchange 域的内容发生改变,一般用于文件选择器和下拉列表
onselect 文本内容被选中
onsubmit 表单提交前触发,回调函数返回 true 表示允许表单提交,返回 false 表示阻止表单提交

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件演示</title>
    <style>
        #img {
            width: 120px;
            height: 120px;
        }
        #head {
            display: none;
        }
    </style>
    <script>
        // 当页面加载完成后运行以下代码
        window.onload = function() {
            // 绑定文本输入框的事件处理函数
            document.getElementById("username").onfocus = function() {
                console.log("文本框获得焦点");
            };
            document.getElementById("username").onblur = function() {
                console.log("文本框失去焦点");
            };
            document.getElementById("username").onselect = function() {
                console.log("文本内容被选中");
            };

            // 绑定文件选择框的事件处理函数
            document.getElementById("head").onchange = function() {
                console.log("文件选择发生变化"); // 在控制台输出文件选择发生变化

                // 获取文件选择框的 DOM 对象
                var fileInput = document.getElementById("head");

                // 检查是否选择了文件
                if (fileInput.files.length > 0) {
                    // 在控制台输出已选择的文件名
                    console.log("文件已选择: " + fileInput.files[0].name);

                    // 使用 URL.createObjectURL 方法创建一个指向所选文件的 URL
                    var imgSrc = window.URL.createObjectURL(fileInput.files[0]);

                    // 将 img 标签的 src 属性设置为所选文件的 URL,以显示文件预览
                    document.getElementById("img").src = imgSrc;
                }
            };

            // 绑定表单的 onsubmit 事件处理函数
            document.getElementById("myForm").onsubmit = function(event) {
                console.log("表单提交前触发");
                var username = document.getElementById("username").value;
                if (username === "") {
                    console.log("用户名不能为空");
                    event.preventDefault(); // 阻止表单提交
                    return false;
                }
                console.log("表单验证通过,允许提交");
                return true;
            };
        };
    </script>
</head>
<body>

    <!-- 表单,包含文本输入框、复选框、文件选择框 -->
    <form id="myForm">
        <!-- 文本输入框,用于输入用户名 -->
        用户名:<input type="text" id="username"><br><br>
        
        <!-- 复选框,用于选择爱好 -->
        爱好:<input type="checkbox" id="programming" value="programming">
        <label for="programming">编程</label><br><br>
        
        <!-- 文件选择框和头像预览 -->
        头像:<input type="file" id="head">
        <label for="head">
            <img src="images/default.png" alt="头像" id="img">
        </label><br><br>

        <!-- 提交按钮 -->
        <button type="submit">提交</button>
    </form>

</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

# 3.4 表单元素的方法

  • focus():使表单元素获得焦点。
  • blur():使表单元素失去焦点。
  • select():选中表单元素中的文本。
  • click():触发表单元素的点击事件。

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>表单方法示例</title>
    <script>
        function focusInput() {
            document.getElementById("myInput").focus();
        }
        function blurInput() {
            document.getElementById("myInput").blur();
        }
        function selectInput() {
            document.getElementById("myInput").select();
        }
        function clickButton() {
            document.getElementById("myButton").click();
        }
    </script>
</head>
<body>
    <input type="text" id="myInput" value="Hello World">
    <button type="button" id="myButton">按钮</button>
    <br>
    <button onclick="focusInput()">获得焦点</button>
    <button onclick="blurInput()">失去焦点</button>
    <button onclick="selectInput()">选中文本</button>
    <button onclick="clickButton()">触发按钮点击</button>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 3.5 复选框的全选案例

以下是一个实现复选框全选功能的案例。当点击表格顶部的全选复选框时,会选中或取消选中表格中所有的复选框:

    <h1>表格全选功能示例</h1>
    <table>
        <thead>
            <tr>
                <!-- 全选复选框 -->
                <th><input type="checkbox" id="selectAll"></th>
                <th>姓名</th>
                <th>年龄</th>
                <th>性别</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <!-- 行复选框 -->
                <td><input type="checkbox" name="selectRow"></td>
                <td>张三</td>
                <td>25</td>
                <td>男</td>
            </tr>
            <tr>
                <!-- 行复选框 -->
                <td><input type="checkbox" name="selectRow"></td>
                <td>李四</td>
                <td>28</td>
                <td>女</td>
            </tr>
            <tr>
                <!-- 行复选框 -->
                <td><input type="checkbox" name="selectRow"></td>
                <td>王五</td>
                <td>30</td>
                <td>男</td>
            </tr>
        </tbody>
    </table>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    table {
        width: 100%;
        border-collapse: collapse; /* 合并边框 */
    }
    th, td {
        border: 1px solid #ddd; /* 单元格边框 */
        padding: 8px; /* 单元格内边距 */
        text-align: center; /* 单元格文本居中 */
    }
    th {
        background-color: #f2f2f2; /* 表头背景颜色 */
    }
    h1 {
        text-align: center; /* 标题居中 */
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
      // 当页面加载完成后运行以下代码
      window.onload = function () {
          // 获取全选复选框和所有行中的复选框
          var selectAllCheckbox = document.getElementById("selectAll");
          var checkboxes = document.querySelectorAll("input[name='selectRow']");
    
          // 全选复选框点击事件处理函数
          selectAllCheckbox.onclick = function () {
              for (var i = 0; i < checkboxes.length; i++) {
                  // 将所有行复选框的选中状态设置为与全选复选框一致
                  checkboxes[i].checked = this.checked;
              }
          };
    
          // 每个行复选框点击事件处理函数
          for (var i = 0; i < checkboxes.length; i++) {
              checkboxes[i].onclick = function () {
                  if (!this.checked) {
                      // 如果某个行复选框未选中,则取消全选复选框的选中状态
                      selectAllCheckbox.checked = false;
                  } else {
                      var allChecked = true;
                      // 检查是否所有行复选框都被选中
                      for (var j = 0; j < checkboxes.length; j++) {
                          if (!checkboxes[j].checked) {
                              allChecked = false;
                              break;
                          }
                      }
                      // 如果所有行复选框都被选中,则设置全选复选框的选中状态
                      selectAllCheckbox.checked = allChecked;
                  }
              };
          }
      };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    // Make sure to add code blocks to your code group

    # 3.6 事件绑定方式

    在JavaScript中,有多种方式可以绑定事件处理函数,主要的方式有两种:

    1. 直接在 window 对象上绑定事件。
    2. 在特定的DOM元素对象上绑定事件。

    作用范围

    • 全局事件绑定:绑定在 window 对象上的事件处理函数会响应整个窗口内的事件,无论用户点击窗口中的哪个位置。
    • 元素事件绑定:绑定在特定DOM元素上的事件处理函数只会响应该元素的事件,例如点击、悬停等。

    事件目标

    • 全局事件绑定:在事件处理函数中,this 关键字指向 window 对象。
    • 元素事件绑定:在事件处理函数中,this 关键字指向事件目标元素(即触发事件的元素)。

    # 1. 绑定全局事件(window 对象)

    当你在 window 对象上绑定事件时,这个事件处理函数将会在整个窗口范围内有效。无论点击窗口中的哪个位置,事件处理函数都会被触发。

    // 绑定鼠标单击事件到 window 对象
    window.onclick = function() {
        console.log("鼠标单击事件");
    };
    
    1
    2
    3
    4

    # 2. 绑定特定元素的事件

    当你在特定的DOM元素对象上绑定事件时,这个事件处理函数只会在该元素上触发。例如,只有当用户点击指定按钮时,事件处理函数才会被调用。

    // 获取DOM对象
    var btn = document.getElementById("btn");
    // 通过直接赋值的方式绑定事件处理函数
    btn.onclick = function() {
        console.log("按钮被点击");
    };
    
    1
    2
    3
    4
    5
    6

    # 4. 事件操作

    # 4.1 事件流

    概念:当一个HTML元素产生事件时,该事件会在当前元素(当前标签)与根元素(html标签)之间按特定的顺序传播,所有经过的节点都会收到该事件并执行,这个传播过程就是DOM事件流。

    分类:事件冒泡、事件捕获

    # 4.2 事件冒泡/事件捕获

    • 事件冒泡:当一个元素上的事件被触发时,事件从事件源开始,往上冒泡直到页面的根元素(沿着DOM树向上传播),这一过程被称为事件冒泡(默认方式)。
    • 事件捕获:当一个元素上的事件被触发时,事件从页面的根元素开始,往下直到事件目标元素(沿着DOM树向下传播),这一过程被称为事件捕获。

    阻止事件冒泡 :event.stopPropagation()

    # 4.2.1 事件冒泡示例

    • 当点击最内部的标签时,事件会从当前标签冒泡到根元素,依次触发各级父元素的事件处理函数。

    • 当点击最内层的 <div id="inner"> 时,事件会冒泡到 <div id="middle"> 和 <div id="outer">,依次触发各自的点击事件。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件冒泡示例</title>
        <style>
            .box {
                border: 1px solid;
                padding: 20px;
                margin: 10px;
            }
        </style>
    </head>
    <body>
        <!-- 外层DIV -->
        <div id="outer" class="box" style="border-color: red;">
            Outer DIV
            <!-- 中间层DIV -->
            <div id="middle" class="box" style="border-color: green;">
                Middle DIV
                <!-- 内层DIV -->
                <div id="inner" class="box" style="border-color: blue;">
                    Inner DIV
                </div>
            </div>
        </div>
    
        <script>
            // 事件冒泡示例
            // 给外层DIV绑定点击事件
            document.getElementById("outer").addEventListener("click", function(event) {
                console.log("Outer DIV Clicked");
            });
    
            // 给中间层DIV绑定点击事件
            document.getElementById("middle").addEventListener("click", function(event) {
                console.log("Middle DIV Clicked");
            });
    
            // 给内层DIV绑定点击事件
            document.getElementById("inner").addEventListener("click", function(event) {
                console.log("Inner DIV Clicked");
            });
        </script>
    </body>
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46

    image-20240720132119941

    # 4.2.2 事件捕获示例

    • 当点击最内部的标签时,事件会从根元素开始捕获,依次触发各级父元素的事件处理函数,最后触发当前标签的事件处理函数。

    • 当点击最内层的 <div id="inner"> 时,事件会从根元素开始捕获,依次触发 <div id="outer"> 和 <div id="middle">,最后触发 <div id="inner"> 的点击事件。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件捕获示例</title>
        <style>
            .box {
                border: 1px solid;
                padding: 20px;
                margin: 10px;
            }
        </style>
    </head>
    <body>
        <!-- 外层DIV -->
        <div id="outer" class="box" style="border-color: red;">
            Outer DIV
            <!-- 中间层DIV -->
            <div id="middle" class="box" style="border-color: green;">
                Middle DIV
                <!-- 内层DIV -->
                <div id="inner" class="box" style="border-color: blue;">
                    Inner DIV
                </div>
            </div>
        </div>
    
        <script>
            // 事件捕获示例
            // 给外层DIV绑定点击事件,并开启捕获模式
            // `addEventListener` 方法的第3个参数是可选参数,布尔值,
            // 表示事件是否在捕获阶段执行。默认值为 `false`代表事件在冒泡阶段执行
            document.getElementById("outer").addEventListener("click", function(event) {
                console.log("Outer DIV Clicked (Capture)");
            }, true);
    
            // 给中间层DIV绑定点击事件,并开启捕获模式
            document.getElementById("middle").addEventListener("click", function(event) {
                console.log("Middle DIV Clicked (Capture)");
            }, true);
    
            // 给内层DIV绑定点击事件,并开启捕获模式
            document.getElementById("inner").addEventListener("click", function(event) {
                console.log("Inner DIV Clicked (Capture)");
            }, true);
        </script>
    </body>
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48

    image-20240720132013569

    # 4.2.3 阻止事件冒泡示例

    • 在内层标签的事件处理函数中阻止事件冒泡,事件不会继续传播到父元素。

    • 当点击最内层的 <div id="inner"> 时,事件只会在 <div id="inner"> 触发,因 event.stopPropagation() 方法阻止了事件冒泡,事件不会传播到 <div id="middle"> 和 <div id="outer">。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>阻止事件冒泡示例</title>
        <style>
            .box {
                border: 1px solid;
                padding: 20px;
                margin: 10px;
            }
        </style>
    </head>
    <body>
        <!-- 外层DIV -->
        <div id="outer" class="box" style="border-color: red;">
            Outer DIV
            <!-- 中间层DIV -->
            <div id="middle" class="box" style="border-color: green;">
                Middle DIV
                <!-- 内层DIV -->
                <div id="inner" class="box" style="border-color: blue;">
                    Inner DIV
                </div>
            </div>
        </div>
    
        <script>
            // 事件冒泡示例
            // 给外层DIV绑定点击事件
            document.getElementById("outer").addEventListener("click", function(event) {
                console.log("Outer DIV Clicked");
            });
    
            // 给中间层DIV绑定点击事件
            document.getElementById("middle").addEventListener("click", function(event) {
                console.log("Middle DIV Clicked");
            });
    
            // 给内层DIV绑定点击事件
            document.getElementById("inner").addEventListener("click", function(event) {
                console.log("Inner DIV Clicked");
                event.stopPropagation(); // 阻止事件冒泡
            });
        </script>
    </body>
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47

    image-20240720132050817

    # 4.3 事件代理/事件委托

    概念:利用事件冒泡/事件捕获机制,通过给父元素绑定事件,从而实现对所有子元素的事件管理,无需为每个子元素绑定事件。

    优点:

    1. 减少事件注册,降低内存占用。
    2. 新增元素时实现动态绑定事件。

    示例:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <title>事件代理示例</title>
        <script>
            window.onload = function () {
                // 给父元素绑定事件处理函数
                document.getElementById("parent").addEventListener("click", function (event) {
                    console.log(this); // 这里的this代表绑定事件的对象
                    console.log(event.target); // 这里的event.target代表触发事件的原始对象
                    if (event.target.tagName === "BUTTON") {
                        console.log("Button", event.target.textContent, "被点击");
                    }
                });
            };
        </script>
    </head>
    
    <body>
        <div id="parent" style="border: 1px solid red; padding: 20px;">
            <button>Button 1</button>
            <button>Button 2</button>
        </div>
    </body>
    
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28

    image-20240720142351423

    # 4.4 事件默认行为

    概念:当一个事件发生时浏览器自己会默认做的事情,如:点击链接时默认会跳转,右键点击时默认会弹出菜单。

    阻止事件的默认行为:e.preventDefault();

    示例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>阻止默认行为示例</title>
        <script>
            window.onload = function() {
                // 为链接绑定事件处理函数
                document.getElementById("link").addEventListener("click", function(event) {
                    console.log("链接被点击,但不会跳转");
                    event.preventDefault(); // 阻止默认跳转行为
                });
            };
        </script>
    </head>
    <body>
        <a href="https://www.example.com" id="link">点击我</a>
    </body>
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    # 5. 综合示例

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件处理示例</title>
        <script type="text/javascript">
            window.onload = function() {
                // 1. 获取按钮元素
                var btn = document.getElementById("btn");
    
                // 2. 静态绑定事件
                btn.onclick = function() {
                    console.log("静态绑定事件:按钮被点击");
                };
    
                // 3. 动态绑定事件
                btn.addEventListener('mouseover', function() {
                    console.log("动态绑定事件:鼠标移到按钮上");
                });
    
                // 4. 事件回调函数使用 this 和 event 对象
                btn.onmouseout = function(event) {
                    console.log("鼠标移出按钮");
                    console.log("事件目标元素:", event.target);  // 事件源
                    console.log("事件类型:", event.type);       // 事件类型
                    console.log("鼠标位置:", event.clientX, event.clientY); // 鼠标位置
                    this.style.backgroundColor = "yellow";     // 修改事件源样式
                };
    
                // 5. 阻止默认行为
                var link = document.getElementById("myLink");
                link.onclick = function(e) {
                    e.preventDefault();  // 阻止默认跳转行为
                    console.log("点击链接,但不跳转");
                };
    
                // 6. 事件代理
                var list = document.getElementById("list");
                list.addEventListener('click', function(e) {
                    if (e.target.tagName === 'LI') {
                        console.log("点击了列表项:", e.target.textContent);
                    }
                });
    
                // 动态添加列表项
                var newItem = document.createElement("li");
                newItem.textContent = "新项";
                list.appendChild(newItem);
            }
        </script>
    </head>
    <body>
        <button id="btn">按钮</button>
        <a href="https://example.com" id="myLink">点击这里</a>
        <ul id="list">
            <li>项 1</li>
            <li>项 2</li>
            <li>项 3</li>
        </ul>
    </body>
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    编辑此页 (opens new window)
    上次更新: 2025/01/25, 22:32:05
    DOM
    BOM(浏览器对象模型)

    ← DOM BOM(浏览器对象模型)→

    Theme by Vdoing | Copyright © 2019-2025 程序员scholar
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式