【JS】事件捕获和事件冒泡的区别

news2024/11/13 18:43:16

事件捕获和事件冒泡是指在 DOM 树中处理事件时的两种不同的传播方式。它们之间的主要区别在于事件传播的方向和顺序:

事件捕获(Capture)

  • 方向: 从最外层的祖先元素向目标元素传播。
  • 顺序: 事件首先从最外层的祖先元素开始传播,直到达到目标元素。
  • 应用场景: 可以在捕获阶段对事件进行拦截或预处理。

事件冒泡(Bubble)

  • 方向: 从目标元素向最外层的祖先元素传播。
  • 顺序: 事件从目标元素开始向上冒泡,直到达到最外层的祖先元素。
  • 应用场景: 可以在冒泡阶段对事件进行响应或处理。

区别总结:

  • 方向不同: 捕获是从外向内,冒泡是从内向外。
  • 应用不同: 捕获通常用于预处理或拦截事件,而冒泡通常用于响应或处理事件。

事件传播的三个阶段:

  1. 捕获阶段(Capture Phase): 事件从最外层的祖先元素向目标元素传播。
  2. 目标阶段(Target Phase): 事件到达目标元素。
  3. 冒泡阶段(Bubble Phase): 事件从目标元素向最外层的祖先元素传播。

在实际开发中,你可以根据需要选择在捕获阶段或冒泡阶段处理事件,利用这两种传播方式来实现不同的交互效果和逻辑。

我们可以用addEventListener 的第三个参数capture的取值,形象地看事件捕获和冒泡的区别。capture(布尔值,表示事件是否在捕获阶段触发,默认为false

以下是冒泡的示例,由内向外

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple HTML Project</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
        }

        #parent {
            background-color: #9fc882;
            padding: 20px;
            border: 2px solid #73deaf;
        }

        #child {
            background-color: #c8f0d9;
            padding: 10px;
            margin-top: 10px;
            border: 1px solid #a4e1a5;
        }
    </style>
</head>

<body>
    <h1>Welcome to My Simple HTML Project</h1>

    <div id="parent">Parent Element
        <div id="child">Child Element</div>
    </div>

    <script>
        const parent = document.getElementById('parent');
        const child = document.getElementById('child');

        // 事件捕获阶段(useCapture 为 true)
        // parent.addEventListener('click', () => {
        //     console.log('Parent Element Clicked - Capture Phase');
        // }, true);

        // child.addEventListener('click', () => {
        //     console.log('Child Element Clicked - Capture Phase');
        // }, true);

        // 事件冒泡阶段(useCapture 为 false 或省略)
        parent.addEventListener('click', () => {
            console.log('Parent Element Clicked - Bubble Phase');
        });

        child.addEventListener('click', () => {
            console.log('Child Element Clicked - Bubble Phase');
        });
    </script>
</body>

</html>

这是捕获的示例,由外想内

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple HTML Project</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
        }

        #parent {
            background-color: #9fc882;
            padding: 20px;
            border: 2px solid #73deaf;
        }

        #child {
            background-color: #c8f0d9;
            padding: 10px;
            margin-top: 10px;
            border: 1px solid #a4e1a5;
        }
    </style>
</head>

<body>
    <h1>Welcome to My Simple HTML Project</h1>

    <div id="parent">Parent Element
        <div id="child">Child Element</div>
    </div>

    <script>
        const parent = document.getElementById('parent');
        const child = document.getElementById('child');

        // 事件捕获阶段(useCapture 为 true)
        parent.addEventListener('click', () => {
            console.log('Parent Element Clicked - Capture Phase');
        }, true);

        child.addEventListener('click', () => {
            console.log('Child Element Clicked - Capture Phase');
        }, true);

        // 事件冒泡阶段(useCapture 为 false 或省略)
        // parent.addEventListener('click', () => {
        //     console.log('Parent Element Clicked - Bubble Phase');
        // });

        // child.addEventListener('click', () => {
        //     console.log('Child Element Clicked - Bubble Phase');
        // });
    </script>
</body>

</html>

应用场景示例:

1. 事件代理(Event Delegation)
  • 场景描述: 在一个列表中有多个子项,需要为每个子项添加点击事件监听器。
  • 应用方式:
    • 使用事件冒泡机制,在整个列表的父元素上添加一个点击事件监听器。
    • 在监听器中通过事件对象的 target 属性判断用户点击了哪个子项。
<ul id="myList">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>

<script>
const list = document.getElementById('myList');

list.addEventListener('click', (event) => {
  if (event.target.tagName === 'LI') {
    console.log('Clicked on:', event.target.textContent);
  }
});
</script>
2. 表单验证
  • 场景描述: 在表单提交前需要对表单字段进行验证。
  • 应用方式:
    • 在表单的父元素上添加一个 submit 事件监听器,使用事件捕获阶段。
    • 在捕获阶段中进行表单字段的验证,如果验证不通过,阻止事件的默认行为(即阻止表单提交)。
<form id="myForm">
  <input type="text" id="username" placeholder="Username">
  <input type="password" id="password" placeholder="Password">
  <button type="submit">Submit</button>
</form>

<script>
const form = document.getElementById('myForm');

form.addEventListener('submit', (event) => {
  // 模拟表单验证,这里只是简单示例
  if (!document.getElementById('username').value || !document.getElementById('password').value) {
    event.preventDefault(); // 阻止表单提交
    console.log('Please fill in all fields.');
  }
}, true); // 使用事件捕获阶段
</script>

这些示例展示了如何利用事件捕获和冒泡机制来解决实际的开发场景,提高代码的效率和可维护性。通过合理利用事件传播机制,可以简化事件处理逻辑,减少重复代码,并实现更灵活的交互。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2098908.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++ 面试 - STL】每日 3 题(四)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…

[A-08]ARMv8/ARMv9-Memory-内存空间(动态内存控制器与物理内存设备)

ver0.2 更多精彩内容&#xff0c;请关注微信公众号 # 前言 前序的文章中&#xff0c;已经讲解了ARM架构下管理内存的核心组件MMU的相关背景知识。MMU需要借助页表(Translation Table)衔接起虚拟地址空间和物理内存的空间&#xff0c;实现在一个硬件环境下软件任务的并发执行效…

【不安全的集合类】同步容器(如ConcurrentHashMap)、并发集合(如CopyOnWriteArrayList)

文章目录 一、List的线程不安全二、Set的线程不安全三、Map的线程不安全 日常我们用到的集合的情况会很多&#xff0c;在单线程的情况下&#xff0c;不用考虑到线程安全的问题&#xff0c;但是如果在多线程开发的过程中&#xff0c;我们该选择哪一种类型来保证线程安全性呢 &am…

【网络安全】逻辑漏洞:绕过应用程序重要功能

未经许可,不得转载。 文章目录 正文漏洞影响正文 目标:xxx.com 一个流行的汽车平台,允许用户为经销商留下评论。该平台有一个功能,用户可以点赞评论,并且它限制每个用户对每个评论只能点赞一次。 然而,我找到了绕过的方法(并不是并发)。 在点击“点赞”按钮时拦截请…

Python从0到100(五十七):机器学习-主成分分析机

主成分分析是⼀种常⽤的降维技术&#xff0c;⽤于将⾼维数据集投影到低维空间中&#xff0c;同时保留数据集的主要特征。PCA通过寻找数据中最重要的⽅向&#xff08;主成分&#xff09;&#xff0c;并将数据投影到这些⽅向上来实现降维。 1.基本原理 1、数据中心化&#xff1…

linux-squid代理服务器

squid简介 作为应用层的代理服务软件&#xff0c;Squid 主要提供缓存加速、应用层过滤控制的功能、用来缓冲Internet数据 接受来自人们需要下载的目标&#xff08;object&#xff09;的请求并适当地处理这些请求。也就是说&#xff0c;如果想下载一web页面&#xff0c;他请求…

特殊字符合集(包括各种emoji表情、windows ASCII字符、自定义字母图案等)

██████╗███████╗ ██████╗ ██╔════╝╚══███╔╝██╔═══██╗ ███████╗ ███╔╝ ██║ ██║ ╚════██║ ███╔╝ ██║▄▄ ██║ ███████║███████╗╚██████╔╝ ╚══════╝…

【小呆的热力学笔记】典型热机-燃气轮机的理想热力循环

文章目录 6.1 燃气轮机的理想热力循环6.2 燃气轮机理想热力循环热效率分析6.3 燃气轮机的理想热力循环讨论 6.1 燃气轮机的理想热力循环 燃气轮机装置主要包含三个部件&#xff1a;压气机、燃烧室和涡轮&#xff0c;详见下图示意。其中压气机主要有离心式和轴流式两种&#xf…

视频素材网站无水印的有哪些?热门视频素材网站分享!

今天我们要讨论一个让许多人都感到困扰的问题——那些高质量、无水印的视频素材到底应该在哪里寻找&#xff1f;是不是有时候感觉&#xff0c;找到合适的视频素材比找到理想的伴侣还要困难&#xff1f;不用急&#xff0c;今天我要介绍几个隐藏的宝藏网站&#xff0c;确保你在视…

ARM 异常处理(21)

异常的流程&#xff1a; 首先&#xff1a; 在硬件上阶段&#xff1a; 这里是4大步3小步 然后是 异常处理&#xff1a; 这里主要是保存现场&#xff0c;进行异常处理 然后是 异常返回&#xff1a; 主要指 恢复现场&#xff0c; 再跳转回去。 首先硬件上&#xff…

Scalefit为外骨骼辅助设备提供直观的损伤减轻测量方案

外骨骼辅助设备是有效减轻工厂中工人遭受肌肉骨骼类疾病损伤的有效工具&#xff0c;但想要更加精确直观的看到外骨骼设备能够为工人提供多少精确到数字的帮助&#xff0c;则需要专业的测量工具来实现。 Scalefit人体工程学分析软件 scalefit人体工程学分析软件让作业环境更安全…

北斗GPS车载定位终端,物流货运数智化效率助手

物流行业&#xff0c;作为国民经济的动脉&#xff0c;其效率与成本控制是企业竞争力的关键。随着科技的不断进步&#xff0c;北斗GPS车载定位终端的出现&#xff0c;正成为物流行业数智化转型的加速器&#xff0c;极大地提升了物流货运的效率与安全性。 北斗GPS车载定位终端&a…

计算机毕业设计python停车场车位推荐管理系统y4uzk

目录 博主介绍技术栈&#x1f31f;文末获取源码数据库&#x1f31f;详细视频演示具体实现截图系统设计数据库设计解决的思路python-flask核心代码部分展示可行性论证个人心得操作可行性源码获取 博主介绍 &#x1f447;&#x1f3fb; 博主介绍&#xff1a;&#x1f447;&#…

【软件测试专栏】软件测试 — 用例篇

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;软件测试专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 软件测试 — 用例篇 关键词&#xff1a;测试用例概念、测试用例的…

【基础】Three.js加载纹理贴图、加载外部gltf格式文件

1. 模型使用纹理贴图 const geometry new THREE.BoxGeometry(10, 10, 10);const textureLoader new THREE.TextureLoader(); // 创建纹理贴图加载器const texture textureLoader.load("/crate.gif"); // 加载纹理贴图const material new THREE.MeshLambertMater…

运维问题0001:MM模块-MIGO收货报错“消息号 M7036 对于采购订单********无收货可能”

1、问题解析&#xff1a; 该报错为SAP标准报错类型,针对公司不同配置/业务设计/校验逻辑&#xff0c;导致该问题原因比较多。 常见的问题总结如下&#xff1a; 1&#xff09;输入的PO信息有问题&#xff08;例如&#xff1a;PO输入错误/PO删除状态/PO冻结状态/PO已完成收货等…

HCIE认证要学多久?3个方面决定HCIE学习时长

HCIE认证作为华为公司推出的顶级专业认证&#xff0c;已经成为网络技术领域内的一个标杆。 它不仅象征着专业技能的高峰&#xff0c;也是许多IT专业人士职业发展的重要里程碑。 HCIE作为华为高级认证虽然可以不需要满足任何条件直接报考&#xff0c;但掌握必要的知识内容必不可…

MySQL复习2

高级查询 准备 create database greatselect; use greatselect;drop table if exists class; create table class (cid int(11) not null auto_increment,caption varchar(32) not null,primary key (cid) )engine innoDB AUTO_INCREMENT5 default charset utf8;create tab…

报考条件、材料、流程?关于CISP认证,你必须要了解这些

信息安全一直是一个火热的话题&#xff0c;在近两年又被推上了高峰。对此&#xff0c;相关认证也不例外。 很多朋友都想get一本安全方向的证书&#xff0c;在广大安全方向的认证中&#xff0c;CISP可谓是发展迅猛&#xff0c;并越来越广为人知&#xff0c;也越来越受到IT从业者…

python Bokeh库学习记录

First steps 2: 添加和自定义渲染器 在之前的入门指南中&#xff0c;你使用了Bokeh的figure()函数来绘制折线图。 在本节中&#xff0c;你将使用不同的渲染函数来创建各种其他类型的图表。你还将自定义你的图像外观。 渲染不同的图形符号 Bokeh的绘图界面支持多种不同的图形…