DOM事件流

news2025/1/13 7:29:28

DOM事件流

  • 1. 常用事件绑定方式
    • 1.1 对象属性绑定
    • 1.2 addEventListener()绑定
    • 1.3 两种方式区别
  • 2. 事件流
    • 2.1 概念
    • 2.2 事件顺序
      • 2.2.1 捕获阶段
      • 2.2.2 目标阶段
      • 2.2.3 冒泡阶段
  • 3. 阻止事件冒泡
    • 3.1 event.stopPropagation()
    • 3.2 stopPropagation与stopImmediatePropagation区别
  • 4. 事件流实战

1. 常用事件绑定方式

1.1 对象属性绑定

<button id="btn">点我</button>
<script>
  var btn = document.getElementById("btn");
  btn.onclick = function() {
    console.log("事件触发")
  }
</script>

1.2 addEventListener()绑定

<button id="btn">点我</button>
<script>
  var btn = document.getElementById("btn");
  btn.addEventListener("click", function () { 
    console.log("事件触发");
  });
</script>

addEventListener第三个参数,Boolean类型值,可指定事件冒泡阶段还是捕获阶段触发,true-捕获,false-冒泡,默认false,既冒泡。

1.3 两种方式区别

  • 对象属性绑定方式只能绑定一次,重复绑定同一事件类型,前面的会被后面的覆盖

下面代码中,“事件触发-1”不会执行了,被下面的onclick覆盖了
其实这种类似对象属性,同一个key,重新赋值会覆盖前面的值

<button id="btn">点我</button>
<script>
  var btn = document.getElementById("btn");
  btn.onclick = function() {
    console.log("事件触发-1")
  }
  btn.onclick = function() {
    console.log("事件触发-2")
  }
</script>

addEventListener没有重复绑定覆盖的问题,同一元素可以绑定同一事件类型多次

下面代码中,按钮点击时,事件会依次触发

<button id="btn">点我</button>
<script>
  var btn = document.getElementById("btn");
  btn.addEventListener("click", function () { 
    console.log("事件触发-1");
  });
  btn.addEventListener("click", function () { 
    console.log("事件触发-2");
  });
  btn.addEventListener("click", function () { 
    console.log("事件触发-3");
  });
</script>

2. 事件流

2.1 概念

事件发生时会在元素节点与根节点之间按照特定的顺序传播,路径所经过的所有节点都会收到该事件,这个传播过程即DOM事件流。

2.2 事件顺序

<div id="root">
  <button id="btn">点我</button>
</div>

2.2.1 捕获阶段

在页面中点击button,首先document接收到click事件,然后沿着dom树,依次向下,直到实际事件触发元素,既button节点,这一过程称为事件捕获过程,是从外到内的传播过程。

2.2.2 目标阶段

经过事件捕获阶段后,然后是实际目标接收到事件即处于目标阶段

2.2.3 冒泡阶段

从目标元素,沿着dom树,逐级向上传递,直到document对象
下图是事件流模型,记为 洋葱模型(先外到内,再内到外)

在这里插入图片描述

历史背景不讲了,总结以下几点:

  1. 默认情况下浏览器以事件冒泡形式进行事件传播
  2. 一刀插过洋葱,先外到内,再内到外,既事件流先由最外层document捕获到目标元素,再经目标元素冒泡到document
  3. 如果要触发捕获阶段事件,在上面介绍的方法addEventListener设置第三个参数为false即可

3. 阻止事件冒泡

3.1 event.stopPropagation()

有时父元素和其子元素都绑定了同一类型事件,我们不想让事件向上传播,触发哪个元素的事件,就执行那个元素的事件处理,不干扰其他元素事件。
这时就需要阻止事件冒泡

方法:event.stopPropagation()

<div id="root">
   <button id="btn">点我</button>
</div>
<script>
  var root = document.getElementById("root");
  var btn = document.getElementById("btn");
  btn.addEventListener("click", function (event) { 
    event.stopPropagation();
    console.log("btn-事件触发");
  });
  root.addEventListener("click", function () { 
    console.log("root-事件触发");
  });
</script>

上面的代码中,rootclick事件不会触发了。

3.2 stopPropagation与stopImmediatePropagation区别

相同点

都能阻止事件冒泡

不同点

stopImmediatePropagation()阻止事件冒泡并且阻止该元素上同事件类型的监听器被触发

举例

1、stopPropagation只能单纯的阻止冒泡

<div id="root">
   <button id="btn">点我</button>
</div>
<script>
  var root = document.getElementById("root");
  var btn = document.getElementById("btn");
  btn.addEventListener("click", function (event) { 
    event.stopPropagation();
    console.log("btn-事件触发1");
  });
  btn.addEventListener("click", function () { 
    console.log("btn-事件触发2");
  });
  root.addEventListener("click", function () { 
    console.log("root-事件触发");
  });
</script>

在这里插入图片描述
2、stopImmediatePropagation 阻止后面同类型事件触发

<div id="root">
   <button id="btn">点我</button>
</div>
<script>
  var root = document.getElementById("root");
  var btn = document.getElementById("btn");
  btn.addEventListener("click", function (event) { 
    event.stopImmediatePropagation();
    console.log("btn-事件触发1");
  });
  btn.addEventListener("click", function () { 
    console.log("btn-事件触发2");
  });
  root.addEventListener("click", function () { 
    console.log("root-事件触发");
  });
</script>

在这里插入图片描述

注意stopImmediatePropagation,只能阻止后面事件不触发
下面代码中,只有”btn-事件触发3“不执行

<div id="root">
   <button id="btn">点我</button>
</div>
<script>
  var root = document.getElementById("root");
  var btn = document.getElementById("btn");
  btn.addEventListener("click", function () {
    console.log("btn-事件触发1");
  });
  btn.addEventListener("click", function (event) {
    event.stopImmediatePropagation();
    console.log("btn-事件触发2");
  });
  btn.addEventListener("click", function () {
    console.log("btn-事件触发3");
  });
  root.addEventListener("click", function () {
    console.log("root-事件触发");
  });
</script>

在这里插入图片描述

4. 事件流实战

<div id="root">
  <button id="btn">点我</button>
</div>
<script>
  var root = document.getElementById("root");
  var btn = document.getElementById("btn");
  document.addEventListener(
    "click",
    function () {
      console.log("document-捕获");
    },
    true
  );
  document.addEventListener("click", function () {
    console.log("document-冒泡");
  });
  root.addEventListener(
    "click",
    function () {
      console.log("root-捕获");
    },
    true
  );
  root.addEventListener("click", function () {
    console.log("root-冒泡");
  });
  btn.addEventListener(
    "click",
    function () {
      console.log("btn-捕获");
    },
    true
  );
  btn.addEventListener("click", function () {
    console.log("btn-冒泡");
  });
</script>

在这里插入图片描述


我是搬运工

作者:勇敢快乐的风筝
链接:https://www.jianshu.com/p/236f4e0beda9
来源:简书

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

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

相关文章

“科技助力财富增值 京华四季伴您一生”,北银理财深化线下线上客户交流互动

2023年4月12日&#xff0c;北银理财有限责任公司&#xff08;以下简称“北银理财”&#xff09;携手东方财富网启动北银理财财富号&#xff0c;首次采用线上直播及线下主题演讲相结合的方式&#xff0c;在上海举办以“科技助力财富增值&#xff0c;京华四季伴您一生”为主题的机…

6、springboot快速使用

文章目录 1、最佳实践1.1、引入场景依赖1.2、查看自动配置了哪些&#xff08;选做&#xff09;1.3、是否需要修改配置1、修改配置2、自定义加入或者替换组件3、自定义器 XXXXXCustomizer 2、开发小技巧2.1、Lombok1、引入坐标2、在IDEA中安装lombok插件&#xff08;新版默认安装…

趣说数据结构 —— 前言

趣说数据结构 —— 前言 一次偶然的机会&#xff0c;翻到当初自己读大学的时候教材&#xff0c;看着自己当初的勾勾画画&#xff0c;一时感触良多。 很值得一提的是&#xff0c;我在封面后第一页&#xff0c;写着自己的专业和名字的地方下面&#xff0c;写着几行这样的字&…

leetcode刷题(6)

各位朋友们大家好&#xff0c;今天是我的leetcode刷题系列的第六篇。这篇文章将与队列方面的知识相关&#xff0c;因为这些知识用C语言实现较为复杂&#xff0c;所以我们就只使用Java来实现。 文章目录 设计循环队列题目要求用例输入提示做题思路代码实现 用栈实现队列题目要求…

Vue2-黑马(七)

目录&#xff1a; &#xff08;1&#xff09;router-路由嵌套 &#xff08;2&#xff09;router-路由跳转 &#xff08;3&#xff09;router-导航菜单 &#xff08;1&#xff09;router-路由嵌套 我们有这样的需求&#xff0c;我们已经显示了主页&#xff0c;但是主页里面有&…

SpringBoot数据库换源

文章目录 前言一. baomidou提供换源注解 DS二. 手动数据源切换三. AOP自动换源 前言 笔者知道有三种方式: baomidou提供的DS自定义AOP自动换源实现AbstractRoutingDataSource手动换源 一. baomidou提供换源注解 DS 注意 1.不能使用事务&#xff0c;否则数据源不会切换&…

云原生入门

云原生入门. 云原生是一种设计和构建应用程序的方法&#xff0c;它充分利用了云计算的优势&#xff0c;如弹性、可扩展性、自动化和敏捷性。云原生应用程序不仅可以在云中运行&#xff0c;而且是为云而生的&#xff0c;它们采用了一些新式的技术和架构模式&#xff0c;使得应用…

零基础入门python好学么

python对于零基础的小伙伴算是非常友好的了~ python以简单易学著称~ Python简洁&#xff0c;高效的特点&#xff0c;大大提升了程序员的编码速度&#xff0c;极大的提高了程序员的办公效率&#xff0c;比如用其他编程语言5、6行代码才能整明白的&#xff0c;用Python可能1-2行就…

不应使用Excel进行项目资源规划的 7 个原因

项目资源规划早期仅限于基本分配和调度。因此&#xff0c;企业使用自制工具或excel表来执行这一简单功能。然而&#xff0c;随着技术和业务流程的发展&#xff0c;资源规划变得复杂&#xff0c;并包括其他组成部分&#xff0c;如预测和容量规划&#xff0c;优化等。 由于传统…

1.BootstrapTable组件

1.先在页面声明一个表格对象 <table id"table" class"table table-striped"></table> 2.生成表格JS代码如下 var url /log/;var columns [{checkbox: true,visible: true //是否显示复选框},{field: id,title: 序号,width…

若依框架—基于AmazonS3实现OSS对象存储服务

若依框架—基于AmazonS3实现OSS对象存储&#xff0c;其他也适用 文章目录 若依框架—基于AmazonS3实现OSS对象存储&#xff0c;其他也适用上一篇[若依mybatis升级mybatis-plus&#xff0c;其他也适用](https://blog.csdn.net/omnipotent_wang/article/details/128635654?spm10…

MYSQL:查询数据

一、学习目标 了解基本查询语句掌握表单查询的方法掌握如何使用几何函数的查询掌握连接查询的方法掌握如何使用子查询熟悉合并查询结果熟悉如何为表和字段取别名掌握如何使用正则表达式查询掌握数据表的查询操作技巧和方法 二、实验内容 根据不同条件对表进行查询操作&#…

Unity Game FrameWork—模块使用—对象池使用

使用对象池&#xff0c;需继承ObjectBase。首先创建一个OPGame的类&#xff0c;继承于ObjectBase&#xff0c;我们暂且把它叫做OP对象&#xff0c;如下图 OP对象有两个地方可以存储成员对象或变量&#xff0c;一个是在OP对象内部如模型ID&#xff1a;m_ModelID。另一个则是对…

【LeetCode训练营02】两个非空链表相加 详解

目录 题目 解题思路的分享 解题源码的分享 题目 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以…

Executor框架简介

Executor系统中&#xff0c;将线程任务提交和任务执行进行了解耦的设计; 线程被一对一映射为服务所在操作系统线程&#xff0c;启动时会创建一个操作系统线程&#xff1b;当该线程终止时&#xff0c;这个操作系统线程也会被回收 Executor框架包含的核心接口和主要的实现类 具体…

Linux下安装Hive

文章目录 1. 确保linux环境下mysql已安装2. 上传安装包3. 解压安装包4. 修改目录名称5. 配置环境变量6. 解压日志jar包冲突7. 拷贝mysql驱动jar包8. 配置hive的参数文件9. 增加hadoop的配置参数10.在mysql中进行相关配置11. 初始化hive的元数据库 1. 确保linux环境下mysql已安装…

【Android】之【WebView】

一、简介 WebView是一种控件&#xff0c;它基于webkit引擎&#xff0c;因此具备渲染Web页面的功能。   基于Webview的混合开发&#xff0c;就是在 Android os(安卓)/I os(苹果)原生APP里&#xff0c;通过WebView控件嵌入Web页面。 你手机里有淘宝软件吧&#xff1f; 就是外…

uniapp开发微信小程序分包处理实录

uniapp开发微信小程序上传代码时可能会遇到项目过大问题&#xff0c;今天就结合自己的实际操作简单记录下如何处理项目代码超出限制问题。 常用的操作就是将项目中的图片访问由本地访问修改为网络访问&#xff0c;微信开发者工具上传代码时勾选相关的压缩文件选项等&am…

CV开启大模型时代!谷歌发布史上最大ViT:220亿参数,视觉感知力直逼人类

ViT模型何时才能破万亿&#xff1f; Transformer无疑是促进自然语言处理领域繁荣的最大功臣&#xff0c;也是GPT-4等大规模语言模型的基础架构。 不过相比语言模型动辄成千上万亿的参数量&#xff0c;计算机视觉领域吃到Transformer的红利就没那么多了&#xff0c;目前最大的…

《华为机试》——MP3光标位置 及 洗牌

本期&#xff0c;我给大家带来以下两个题目的讲解&#xff1a; 1、《华为机试》——MP3光标位置 &#xff08;中等&#xff09;2、 2017年校招真题——洗牌 &#xff08;简单&#xff09; 以上两个题的难度属于我也给大家标注出来了&#xff0c;接下来&#xff0c;我们一起去…