js事件流与事件委托/事件代理

1 事件流

事件流分为两步,一是捕获,二是冒泡
在这里插入图片描述

1.1 捕获概念

捕获就是从最高层一层一层往下找到最内部的节点

1.2 冒泡概念

捕获到最小节点后,一层一层往上返回,像是气泡从最底部往上冒一样,由于水深不同压强不同,同样多的气体越往上冒气泡越大,就像在html里越往上走“辈分”越大一样,所以比喻成冒泡

1.3 事件默认触发是在捕获阶段还是冒泡阶段?

默认是冒泡阶段
考虑如下层级

<div class="grandpa"><div class="father"><div class="son"></div></div>
</div>

为这三个div添加事件

const grandpa = document.querySelector(".grandpa");
const father = document.querySelector(".father");
const son = document.querySelector(".son");grandpa.onclick = function() {console.log('grandpa');
}
father.onclick = function() {console.log('father');
}
son.onclick = function() {console.log('son');
}

添加样式:

*{margin: 0;padding: 0;
}
.grandpa {margin: 200px auto;
}.grandpa {width: 400px;height: 400px;background-color: blue;
}
.father {width: 300px;height: 300px;background-color: skyblue;
}
.son {width: 200px;height: 200px;background-color: pink;
}

在这里插入图片描述

考虑点击粉色区域时, 输出顺序是什么?点此跳转查看上述案例

son
father
grandpa

如果是捕获时触发事件,则顺序应当相反

1.4 阻止冒泡

son.onclick = function(event) {console.log('son');event.stopPropagation();
}

如上代码, 事件会默认向函数里传入一个event事件, 调用event.stopPropagation();事件即可在当前位置阻止冒泡
这样点击son的显示区域时只会输出son


如果想要在点击son的区域时, 只将冒泡传递到father, 即触发father但是不触发grandpa的onclick事件, 可以如下操作:

const grandpa = document.querySelector(".grandpa");
const father = document.querySelector(".father");
const son = document.querySelector(".son");grandpa.onclick = function() {console.log('grandpa');
}
father.onclick = function(event) {console.log('father');event.stopPropagation();
}
son.onclick = function() {console.log('son');
}

2 事件委托/事件代理

事件委托, 又称事件代理
顾名思义, 事件委托, 肯定是把事件委托到别处.
冒泡时触发事件, 那肯定是往上委托
也就是说, 将当前节点的事件交给该节点往上冒泡可达的先辈节点处理


这么说还是有点模糊, 准确来说, 就是son节点不绑定onclick事件, 而是等click事件冒泡到father身上, 在father身上绑定onclick事件, 在father的onclick事件中获取并处理被点击的son

事件冒泡时会将当前节点作为event事件的一个属性target传入, 也就是说相当于event.target = document.getElementById('son')传入了father的onclick事件中

2.1 事件委托的好处

考虑下面例子

<ul class="father"><li class="son">1</li><li class="son">2</li><li class="son">3</li><li class="son">4</li>
</ul>

当点击不同li的时候, 想要触发不同的事件, 例如输出1/2/3/4


传统实现逻辑如下:

const sons = document.querySelectorAll('.son');for(const i = 0; i < sons.length; i++) {sons[i].onclick = function() {console.log(i);}
}

如果页面内容非常多, 例如这里有1000个<li>标签, 那么就需要添加1000次onclick函数, 十分麻烦
这种情况我们可以将事件委托给父元素.
这里需要用到 event.target


不妨试试对class为father的ul添加onclick事件, 输出event, 并点击li所在的区域, 查看event.target输出的是什么

const father = document.querySelector('.father');
father.onclick = function(event) {console.log(event.target);
}

我们点击第四个li:
在这里插入图片描述

可见, 在父元素ul上添加onclick事件, 点击子元素时, 冒泡时会将该子元素传递给过来
据此我们可以对子元素进行处理, 这样我们只在ul上绑定了事件, 就可以处理该ul下所有的li
点击尝试

const father = document.querySelector('.father');
father.onclick = function(event) {console.log(event.target.innerText);// 或者一些对点击的li的其他操作
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git常用命令#更改用户名

1.查看当前用户信息 git config user.name2.更改用户名 特定仓库中更改用户名 如果你只想在特定仓库中更改用户名&#xff0c;可以在不使用 --global 参数的情况下执行相同的命令&#xff0c;并进入特定仓库的目录进行修改。 cd /path/to/your/repository git config user.na…

双通道 H 桥 5V 4A驱动芯片

SS6951A 为电机一体化应用提供一种双通道集成电机驱动方案。SS6951A 有两路 H 桥驱动&#xff0c;每个 H 桥可提供最大峰值电流 4.0A&#xff0c;可驱动两个刷式直流电机&#xff0c;或者一个双极步进电机&#xff0c;或者螺线管或者其它感性负载。双极步进电机可以以整步、2 细…

传统算法:使用 Pygame 实现选择排序

使用 Pygame 模块实现了选择排序的动画演示。首先,它生成一个包含随机整数的数组,并通过 Pygame 在屏幕上绘制这个数组的条形图。接着,通过选择排序算法对数组进行排序,动画效果可视化每一步的排序过程。在排序的过程中,程序找到未排序部分的最小元素,并将其与未排序部分…

基于YOLOv8深度学习的火焰烟雾检测系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

牛客算法题 HJ99 自守数 golang实现

题目 HJ99 自守数 描述 自守数是指一个数的平方的尾数等于该数自身的自然数。例如&#xff1a;25^2 625&#xff0c;76^2 5776&#xff0c;9376^2 87909376。请求出n(包括n)以内的自守数的个数数据范围&#xff1a; 1 ≤ &#xfffd; ≤ 100001≤n≤10000 输入描述&…

LeetCode(44)存在重复元素 II【哈希表】【简单】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 存在重复元素 II 1.题目 给你一个整数数组 nums 和一个整数 k &#xff0c;判断数组中是否存在两个 不同的索引 i 和 j &#xff0c;满足 nums[i] nums[j] 且 abs(i - j) < k 。如果存在&#xff0c;返回 true &#xf…

二进制求和

这篇文章会收录到 : 算法通关村第十三关-白银挑战数字与数学高频问题-CSDN博客 二进制求和 描述 : 给你两个二进制字符串 a 和 b &#xff0c;以二进制字符串的形式返回它们的和。 题目 : LeetCode 67.二进制求和 : 67. 二进制求和 分析 : 这个题也是用字符串来表示数据的…

剪辑素材,6个可白嫖的视频素材网站

找视频素材就上这6个网站&#xff0c;免费下载&#xff0c;赶紧收藏好&#xff01; 1、菜鸟图库 https://www.sucai999.com/video.html?vNTYxMjky 菜鸟图库网素材非常丰富&#xff0c;网站主要以设计类素材为主&#xff0c;高清视频素材也很多&#xff0c;像风景、植物、动物…

【机器学习】集成学习算法之AdaBoost

文章目录 基本步骤示例生成第 1 棵决策树生产第 2 棵决策树生成第 T 棵决策树加权投票 sklearn 实现 基本步骤 首先&#xff0c;是初始化训练数据的权值分布 D 1 D_1 D1​。假设有 m m m 个训练样本数据&#xff0c;则每一个训练样本最开始时&#xff0c;都被赋予相同的权值…

Electron+Ts+Vue+Vite桌面应用系列:sqlite增删改查操作篇

文章目录 1️⃣ sqlite应用1.1 sqlite数据结构1.2 初始化数据库1.3 初始化实体类1.4 操作数据类1.5 页面调用 优质资源分享 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/134692751 ElectronTsVueVite桌面应用系列 &am…

简明指南:使用Kotlin和Fuel库构建JD.com爬虫

概述 爬虫&#xff0c;作为一种自动化从网络上抓取数据的程序&#xff0c;广泛应用于数据分析、信息提取以及竞争对手监控等领域。不同的实现方式和编程语言都能构建出高效的爬虫工具。在本文中&#xff0c;我们将深入介绍如何充分利用Kotlin和Fuel库&#xff0c;构建一个简单…

记i18n ally工具检测语言失败的一则思路

情况 只有某个文件检测不到汉字&#xff0c;其余都可以检测出来&#xff0c;困扰许久&#xff0c;发个博客记一下思路 解决方法&#xff1a; 1、肯定不是i18n ally工具的问题&#xff0c;因为其他的vue都能检测成功 2、是这个文件的问题 采用排除法 先删掉所有代码&#…