JavaScript DOM事件流之捕获与冒泡

news2024/11/14 22:10:00

DOM事件流——捕获与冒泡

网页是由一个一个元素组成的,正如我们肉眼所见,网页上的元素存在包含关系,简单的点击又怎么确定到底谁来触发响应呢?想象一下,在纸上画了两个大小不同的同心圆,然后用手指指向它里面的圆,那么你能说了指向的圆没有包含外面的圆吗?显然不是的,为了解决这个问题,出现了事件流。

DOM事件流三阶段

当用户与HTML页面交互(如点击按钮、移动鼠标等)时,就会产生事件,而DOM结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素节点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程可称为DOM事件流。DOM事件流主要分为三个阶段:捕获阶段、目标阶段、冒泡阶段。

1、捕获阶段Capturing 捕获是由网景公司最先提出的,事件从文档的根节点开始,‌向下传播至目标元素。‌在这个过程中,‌事件会经过目标元素的父元素、‌祖父元素等,‌但通常不会在这个阶段触发事件监听器,‌除非特别指定。这可以用于在事件传播到特定子元素之前,先进行一些全局性的处理或检查。

‌2、目标阶段Target 当事件到达目标元素时,‌事件会被触发,‌并执行绑定在该元素上的事件监听器。监听器就会按照它们被添加到元素上的顺序被调用,不管是捕获还是冒泡事件,只会按添加的顺序执行(注意⚠️:在最新的浏览器版本中如果同时存在默认和冒泡,都会先执行捕获!!!)

3、冒泡阶段Bubbling‌:冒泡是IE最早提出的,事件从目标元素开始,‌向上冒泡至根节点。‌在这个过程中,‌事件同样会经过目标元素的父元素、‌祖父元素等,‌且可以在这些元素上触发事件监听器。‌这通常用于实现事件的委托(Event Delegation),即在一个父元素上监听子元素的事件,从而减少事件监听器的数量,提高性能。在实际开发中我们使用跟多的也是冒泡,很少用到捕获。

在这里插入图片描述

代码示例,单击白色inner盒子,执行结果如下:

<!DOCTYPE html>
<html>
  <head>
    <title>DOM事件流</title>
  </head>
  <body>
    <div class="outer">
      <div class="inner"></div>
    </div>
  </body>
  <script>
    // 获取DOM元素
    let outer = document.querySelector('.outer')
    let inner = document.querySelector('.inner')
    // 绑定事件
    outer.addEventListener('click', () => console.log('outer冒泡阶段'), false) // 5
    outer.addEventListener('click', () => console.log('outer捕获阶段'), true) // 1
    inner.addEventListener('click', () => console.log('inner冒泡阶段'), false) // 4
    inner.addEventListener('click', () => console.log('inner捕获阶段方法1'), true) // 2
    inner.addEventListener('click', () => console.log('inner捕获阶段方法2'), true) //3
  </script>
  <style>
    .outer {
      display: flex;
      align-items: center;
      width: 300px;
      height: 300px;
      background-color: pink;
    }

    .inner {
      margin: 0 auto;
      width: 200px;
      height: 200px;
      background-color: white;
    }
  </style>
</html>

在这里插入图片描述

可见,事件的整体顺序是:祖先元素捕获 -> 目标元素捕获 -> 目标元素冒泡 -> 祖先元素冒泡(⚠️老版本浏览器目标元素可能按绑定顺序执行)

无法冒泡的事件

基本上只有onloadunloadfocusblursubmitchange事件是不支持冒泡的

阻止冒泡

为什么要阻止冒泡

1、提高性能和效率:如果多个元素(如父元素和子元素)都绑定了相同或相似的事件处理函数,并且这些函数都执行了相似的操作,那么当事件发生时,这些函数都会被调用,从而导致重复的计算或处理,浪费资源。通过阻止事件冒泡,可以避免这种不必要的重复处理,提高代码的性能和效率。

2、控制事件传播范围:有时候,我们可能只希望事件在特定的元素上触发,而不希望它继续传播到父元素或祖先元素上。通过阻止事件冒泡,我们可以精确地控制事件的传播范围,确保事件只在目标元素上触发。

3、防止事件的冲突和干扰:在复杂的前端应用中,可能存在多个嵌套的元素,它们都有自己的事件处理逻辑。如果事件冒泡到了父元素或祖先元素,可能会触发其他元素上的事件处理函数,导致事件的冲突和干扰。

如何阻止冒泡

1、stopPropagation()标准方法:利用事件对象里面的stopPropagation()方法

    outer.addEventListener('click', () => console.log('outer冒泡阶段'), false)
    outer.addEventListener('click', () => console.log('outer捕获阶段'), true)
    inner.addEventListener('click', () => console.log('inner冒泡阶段'), false)
    inner.addEventListener(
      'click',
      () => {
        console.log('inner捕获阶段方法1')
        event.stopPropagation()
      },
      true
    )

执行结果如下,在捕获阶段使用stopPropagation()冒泡都被阻止了

在这里插入图片描述

2、cancelBubble兼容性方法:虽然stopPropagation()已被大多数浏览器支持,但IE6-8需要利用事件对象的cancelBubble属性阻止冒泡,即设置:window.event.cancelBubble = true;

3、在事件处理函数中返回false:这个方法很多地方都有提到,但实践起来并不奏效,首先他限定事件处理函数是通过HTML属性(如onclick)或者某些特定的JavaScript库(如jQuery)以特定方式注册的,其次不同浏览器处理方式也不一样,最新的浏览器中大多数已经无法奏效了

4、设置CSS属性:虽然CSS本身不直接提供阻止事件冒泡的功能,但有时候通过改变元素的显示方式(如display: none;)或可交互性(如pointer-events: none;),可以间接影响事件的传播,这个方法具有局限性

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

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

相关文章

第45篇 汇编语言实现中断<一>

Q&#xff1a;DE2-115_Computer System的异常与中断有哪些特点呢&#xff1f; A&#xff1a;DE2-115 Computer系统中的Nios II处理器复位地址为0x00000000。用于处理其它所有普通异常&#xff0c;例如除0以及硬件IRQ中断的地址为0x00000020。Nios II处理器的异常和硬件IRQ中…

C++和OpenGL实现3D游戏编程【连载8】——纹理文字实现与优化

C++和OpenGL实现3D游戏编程【连载8】——纹理文字实现与优化 1、本节达到的效果 上一节课我们介绍了在opengl中文字的显示方法,但显示出来的文字无法旋转,在某些特定游戏要求下,文字是需要进行旋转的,那么这一节课我们介绍一下纹理文字的高级使用方法,将文字生成纹理,达…

一文搞懂性能测试

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 性能测试概念 我们经常看到的性能测试概念&#xff0c;有人或称之为性能策略&#xff0c;或称之为性能方法&#xff0c;或称之为性能场景分类&#xff0c;大概…

mysql和pg等数据库之间的数据迁移实战分享

mysql和pg等数据库之间的数据迁移是常见的问题&#xff1a;比如一开始使用Oracle&#xff0c;后来想使用mysql&#xff0c;而且需要把Oracle数据库的数据迁移到mysql里面&#xff1b;后期有想使用pg数据库&#xff0c;同时需要把Mysql数据库的数据迁移到pgl里面&#xff0c;等等…

shell脚本编写之函数

shell中的函数定义比较简单&#xff0c;定义函数名可以没有类型&#xff0c;函数返回值可有可无&#xff0c;如果有返回值&#xff0c;必须返回整数n&#xff08;0~255&#xff09;。同时&#xff0c;函数的定义必须放在shell脚本的开头部分&#xff0c;只有函数被shell解释器发…

【微机】DOSBox在windows上的安装和masm的配置

本文首发于 ❄️慕雪的寒舍 最近学校学习微型计算机原理与接口技术&#xff0c;需要用到DOSBox来模拟DOS环境进行汇编编程的学习。 本文记录了如何在windows11/10上安装DOSBox0.74并配置masm5 1.安装 这两个软件我打包上传到了百度云盘。放心&#xff0c;加起来也就2mb&…

【多线程】死锁

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. 死锁的三种情况1.1 一个线程一把锁&#xff08;同一个线程给同一个对象加两次锁的情况&#xff09;1.2 两…

Save OpenAI response in Azure function to Blob storage

题意&#xff1a;将 OpenAI 的响应保存在 Azure 函数中到 Blob 存储 问题背景&#xff1a; I used blob trigger template to create an Azure function that is triggered by new file updated in Azure blob storage. I am using python v2 to create Azure function in VSc…

SAP ABAP任意表数据查询+快速下载工具

背景&#xff1a; 项目上业务顾问有时候需要下载标准表大量的数据到Excel进行一些比对&#xff0c;但是标准SE16N&#xff0c;SE16的下载电子表格功能在遇到大批量数据的时候会非常慢&#xff0c;于是抽空写了个通用的查询下载工具&#xff0c;可以快速的下载数据。 工具界面&…

Linux - Linux安装部署xxl-job

一、下载源码 xxl-job源码地址&#xff1a; https://github.com/xuxueli/xxl-job 2.4.2版本为例&#xff1a;https://github.com/xuxueli/xxl-job/archive/refs/tags/2.4.1.tar.gz xxl-job文档地址&#xff1a; 分布式任务调度平台XXL-JOB 二、安装依赖环境 因为需要…

Go语言中的RPC协议原理解析

Go语言中的RPC协议原理解析 在分布式系统中&#xff0c;不同的服务或组件通常运行在不同的计算机或进程上。为了实现这些服务之间的通信&#xff0c;我们可以使用RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;协议。RPC允许我们像调用本地函数一…

【区块链 + 人才服务】FISCO BCOS 高校实训和管理平台 | FISCO BCOS应用案例

深圳市火链文化传播有限公司建设部署 FISCO BCOS 高校实训和管理平台&#xff0c;这是一条多领域覆盖的联盟链&#xff0c;以高 校 政府教育部门 合作企业共同授权成为联盟链节点&#xff0c;实现在政府指导监管下&#xff0c;多行业扩展、多机构参与、多 平台共存的联盟链模…

SparseDrive - 清华地平线开源的e2e的框架

清华地平线合作开发的e2e的框架 SparseDrive资源 论文 https://arxiv.org/pdf/2405.19620 git https://github.com/swc-17/SparseDrive 个人觉得该文章厉害的地方 纯sparse mapping&#xff0c; 3d detection方案, 用的检测头sparse4D V3 sparsev1v2v3基本一致&#xff0c;m…

秒懂:父子进程

1.概念 在操作系统中&#xff0c;当一个进程&#xff08;称为父进程&#xff09;创建另一个新进程&#xff08;称为子进程&#xff09;时&#xff0c;父子进程之间建立了一种特殊的关系。 2.创建父子进程的方法 2.1 fork()函数详解&#xff1a; fork 是一个系统调用&#xff0…

Qt 加载 WPS 时提示要登录

项目中Qt加载word时 默认用wps打开word文档 程序一运行老是提示要立即登录 看着很烦 可以按下面的方法去掉这个烦人的东西 在下面的项目中新建字符串enableforceloginforfirstinstalldevice&#xff0c;值为false即可。

品聚文化--打造票圈神话

热烈祝贺鸿玉祥安文票9月5号正式启动运营 尊敬的各位领导、合作伙伴、客户以及全体品聚的家人们 今天&#xff0c;我们迎来了公司文票正式启动这一历史性的时刻&#xff0c;在此&#xff0c;我谨代表公司及全体员工&#xff0c;向所有关心和支持我们发展的朋友们表示最热烈的祝…

Java进阶13讲__第十讲

IO流、File 1. File 1.1 创建对象 1.1.1 File指向 指向文件 File f1 new File("E:\\TableFace\\Finished\\合同审核.txt"); 指向文件夹 File f2 new File("E:\\TableFace\\Finished"); 指向不存在文件 File f2 new File("E:\\T…

用最简单的话来解释大模型中的Transformer架构

开篇 我个人的观点是要想系统而又透彻地理解 Transformer&#xff0c;至少要遵循下面这样一个思路&#xff08;步骤&#xff09;&#xff1a; 理解NLP基础 在探讨Transformers之前&#xff0c;了解自然语言处理(NLP)的一些基本知识至关重要。NLP使计算机能够理解和生成自然语…

GEE数据集:美国国家结构清单(NSI)用于评估和分析自然灾害的点式结构清单

简介 国家结构清单 国家结构清单&#xff08;NSI&#xff09;是一个数据库系统&#xff0c;其中包含不同质量和空间覆盖范围的结构清单。 NSI 数据库的目的是促进存储和共享用于评估和分析自然灾害的点式结构清单。 洪水风险是主要用途&#xff0c;但每个结构都有足够的数据来…

prompt实用技巧-竞对分析-飞书发布会上多维表和低代码平台原型分析

prompt engineer 工程师的一天 ,竞品分析相关。 “作为企业软件咨询公司整理出uipath,salesforce,airtable,zapier的官网地址&#xff0c;功能点详情&#xff0c;优势&#xff0c;劣势 生成表格4*4&#xff0c;表头为:uipath,salesforce,airtable,zapier, 第一例为&…