DOM事件、冒泡和捕获、事件代理

news/2024/11/18 23:55:29/

DOM是用来呈现以及与任意 HTML 或 XML 文档交互的 API。DOM 是载入到浏览器中的文档模型,以节点树的形式来表现文档,每个节点代表文档的构成部分
DOM事件流有3个阶段:捕获阶段目标阶段冒泡阶段
三个阶段的顺序为:捕获阶段——目标阶段——冒泡阶段;
原因:因为Window对象是直接面向用户的,那么用户触发一个事件,如点击事件,肯定是用window对象开始的,所以自然就是先捕获后冒泡。
不管对于非目标阶段或者目标阶段的元素,事件响应执行顺序都是遵循先捕获后冒泡的原则;通过使用定时器暂缓执行捕获事件,可以达到先冒泡后捕获的效果;
事件捕获是从顶层的Window逐层向内执行,事件冒泡则相反;
事件委托(事件代理)是根据事件冒泡或事件捕获的机制来实现的。

DOM事件流

事件流包括三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。
在DOM事件流中,事件的目标在捕获阶段不会接受到事件。这意味着在捕获阶段,事件从document到p后就定停止了。
  下一个阶段是处于目标阶段,于是事件在p上发生,并在事件处理中被看成冒泡阶段的一部分。然后,冒泡阶段发生,事件又传播回document。
多数支持DOM事件流的浏览器都实现了一种特定的行为;即使“DOM2级事件”规范明确要求捕获阶段不会涉及事件目标,但IE9、Safari、Chrome、Firefox和Opera9.5及更高版本都会在捕获阶段触发事件对象上的事件。结果,就是有两个机会在目标对象上操作事件

addEventListener函数

**MDN定义:**addEventListener() 的工作原理是将实现 EventListener 的函数或对象添加到调用它的 EventTarget 上的指定事件类型的事件侦听器列表中。如果要绑定的函数或对象已经被添加到列表中,该函数或对象不会被再次添加。

addEventListener(type, listener);
addEventListener(type, listener,options);
addEventListener(type, listener, useCapture);

参数
type:表示监听事件类型的大小写敏感的字符串。listener
当所监听的事件类型触发时,会接收到一个事件通知(实现了 Event 接口的对象)对象。
listener 必须是一个实现了 EventListener 接口的对象,或者是一个函数。
useCapture
默认值false,表示事件冒泡;设为true时,表示事件捕获

事件冒泡举例

<div id="1" style="width: 100%; height: 300px;background-color: red;">1<div id="2" style="width: 100%; height: 200px;background-color: blue;">2<div id="3" style="width: 100%; height: 100px;background-color: skyblue;">3</div></div>
</div>
<script>var a = document.getElementById('1')var b = document.getElementById('2')var c = document.getElementById('3')//注册冒泡事件监听器a.addEventListener('click', () => {console.log("冒泡1")})b.addEventListener('click', () => {console.log('冒泡2')})c.addEventListener('click', () => {console.log("冒泡3")})
</script>

冒泡事件的执行顺序为:c -> b -> a

事件捕获举例

<div id="1" style="width: 100%; height: 300px;background-color: red;">1<div id="2" style="width: 100%; height: 200px;background-color: blue;">2<div id="3" style="width: 100%; height: 100px;background-color: skyblue;">3</div></div>
</div>
<script>var a = document.getElementById('1')var b = document.getElementById('2')var c = document.getElementById('3')//注册冒泡事件监听器a.addEventListener('click', () => {console.log("捕获a")}, true)b.addEventListener('click', () => {console.log('捕获b')}, true)c.addEventListener('click', () => {console.log("捕获c")}, true)
</script>

捕获事件的执行顺序为:a -> b -> c

冒泡事件和捕获事件的区别

<div id="1" style="width: 100%; height: 300px;background-color: red;">1<div id="2" style="width: 100%; height: 200px;background-color: blue;">2<div id="3" style="width: 100%; height: 100px;background-color: skyblue;">3</div></div>
</div>
<script>var a = document.getElementById('a')var b = document.getElementById('b')var c = document.getElementById('c')a.addEventListener('click', () => {console.log("冒泡a")})b.addEventListener('click', () => {console.log('冒泡b')})c.addEventListener('click', () => {console.log("冒泡c")})a.addEventListener('click', () => {console.log("捕获a")}, true)b.addEventListener('click', () => {console.log('捕获b')}, true)c.addEventListener('click', () => {console.log("捕获c")}, true)
</script>

事件代理(事件委托)

**事件代理就是利用事件冒泡或事件捕获的机制把一系列的内层元素事件绑定到外层元素。

  • itema
  • itemb
  • itemc
  • itemd

对于上述的列表元素,我们希望将用户点击了哪个item打印出来,通常我们可以给每个item注册点击事件监听器,但是需要对每个元素进行事件监听器的注册;但是通过事件代理,我们可以将多个事件监听器减少为一个,这样就减少代码的重复编写了。利用事件冒泡或事件捕获实现事件代理:
javascript复制代码var items = document.getElementById(‘item-list’);
//事件捕获实现事件代理
items.addEventListener(‘click’, (e) => {console.log('捕获:click ',e.target.innerHTML)}, true);
//事件冒泡实现事件代理
items.addEventListener(‘click’, (e) => {console.log('冒泡:click ',e.target.innerHTML)}, false);
说到这里,大家都明白了,事件代理既可以通过事件冒泡来实现,也可以通过事件捕获来实现


http://www.ppmy.cn/news/103599.html

相关文章

Redis(六)主从模式与哨兵机制

文章目录 一、主从模式配置一主二从集群 二、哨兵机制哨兵模式演示&#xff1a;哨兵如何监控节点「主观下线」与[客观下线]哨兵如何选新主节点由哪个哨兵进行转移如何通知客户端新主节点的信息? 一、主从模式 配置一主二从集群 开启三个linux&#xff0c;并安装redis info …

【Python笔记(1) ——Python基础知识】

文章目录 1. 标识符2. 关键字3. 引号4. 编码5. 输入输出6. 缩进7. 多行8. 注释9. 数据类型10. 运算符10.1 常用运算符10.2 运算符优先级 1. 标识符 在 Python 中标识符是用来标识变量、函数、类等用户自定义对象的命名。标识符的命名规则是&#xff1a; 可以是字母、数字、下…

水处理施工方案合集

编制说明及工程简介 (一) 编制说明 本施工组织设计是依据建设单位提供的招标文件、施工图、同类工程施工资料和国家有关施工规范及验收标准进行编制的。本施工组织设计针对本工程施工中的关键点、难点及其处理措施&#xff0c;主要施工方法&#xff0c;施工组织部署&#xff…

JavaScript实现背景图像切换3D动画效果

&#x1f431; 个人主页&#xff1a;不叫猫先生 &#x1f64b;‍♂️ 作者简介&#xff1a;2022年度博客之星前端领域TOP 2&#xff0c;前端领域优质作者、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &am…

Django从Models 10分钟定制一个Admin后台

简介 Django自带一个Admin后台, 支持用户创建,权限配置和所有模型的增删改查功能, 只需要一些简单的配置就可快速得到一个开箱可用的后台管理系统 操作步骤 1. 更改设置,使用中文/亚洲时区 修改项目下django_shop目录下的settings.py文件 修改以下三行 LANGUAGE_CODE zh-h…

虚拟机配置

配置虚拟机网络 创建虚拟机 20G 4G内存 初始化用户名和密码 zhao 123456 克隆拷贝2个虚拟机 配置内存为2G 修改主机名和固定IP hostnamectl set-hostname node1 hostnamectl set-hostname node2 vim /etc/sysconfig/network-scripts/ifcfg-ens33 systemctl stop network s…

vue中实现任意组件间通信(全局事件总线、消息订阅与发布)

1.全局事件总线&#xff0c;顾名思义&#xff0c;可以适用于任意组件间通信&#xff0c;我们需要通过$bus这个中间傀儡来实现&#xff0c;我们可以把$bus安装到Vue身上&#xff0c;这样可以让所有组件都能看到它&#xff0c; 1.1安装全局事件总线&#xff1a;我们可以在new Vu…

【机器学习】Kullback-Leibler (KL) divergence(KL 散度)

KL 散度是衡量两个概率分布之间差异的方法&#xff0c;我们首先考虑衡量两个概率分布之间差异的意义是什么: 模型评估与选择&#xff1a;在机器学习中&#xff0c;我们需要训练模型来拟合数据的概率分布。衡量预测分布与真实分布之间的差异可以帮助我们评估模型的性能&#xff…