JS事件冒泡与JS事件代理(事件委托)

news/2024/11/29 7:50:53/

JS事件冒泡与JS事件代理(事件委托)

  • 1、事件冒泡
    • 1.1 概念
    • 1.2 要是不给子元素添加具体的oncilck处理方法,也能冒泡么?
    • 1.3 子元素触发的事件冒泡会触发父元素所有的事件么?还是触发对应的事件?
    • 1.4 那么我们应该如何组织这讨厌的事件冒泡机制呢?
  • 2、事件委托(事件代理)
    • 2.1 概念
    • 2.2 for循环遍历给每个li添加事件
    • 2.3 利用事件代理给li添加事件

1、事件冒泡

1.1 概念

通俗来讲,当触发(点击或者触摸之类的做法)有父元素的子元素的时候,事件会从事件源(被点击的子元素)开始逐级向上传播,触发父级元素的点击事件,一直会传到window。如果在某一层想要中止冒泡,使用 event.stopPropagation() 。下面见详细的代码:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>#parent {width: 400px;height: 400px;background-color: blue;display: flex;justify-content: center;align-items: center;}#child {width: 200px;height: 200px;background-color: brown;}</style></head><body><div id="parent"><div id="child"></div></div><script>let parent = document.getElementById('parent')parent.onclick = function () {console.log('parent')}let child = document.getElementById('child')child.onclick = function () {console.log('child')}</script>
</body></html>

在这里插入图片描述
我们可以发现,当点击红色区域(子元素)的时候,父级元素的click事件也被触发了。

接下来看两个示例:

1.2 要是不给子元素添加具体的oncilck处理方法,也能冒泡么?

<script>// let parent = document.getElementById('parent')// parent.onclick = function () {// console.log('parent')// }let child = document.getElementById('child')child.onclick = function () {console.log('child')}</script>

效果如下:
在这里插入图片描述
子元素在没有定义具体的click处理函数的时候仍然可以冒泡,触发父级元素的click事件。

1.3 子元素触发的事件冒泡会触发父元素所有的事件么?还是触发对应的事件?

 <script>let parent = document.getElementById('parent')parent.onkeydown = function () {console.log('parent')}let child = document.getElementById('child')child.onclick = function () {console.log('child')}</script>

结果如下:
在这里插入图片描述
我们发现只有相应的事件会发生事件冒泡,不相关的事件不受影响(注意由于click为鼠标的点击,所以同样会触发mousedown与mouseup等相关事件,同时发生冒泡!)

1.4 那么我们应该如何组织这讨厌的事件冒泡机制呢?

很简单,在事件触发时,会传入一个相应的event对象,其中有一个stopPropagation()方法可以阻止事件冒泡(IE中为cancleBubble=true),以下是详细代码:

 <script>let parent = document.getElementById('parent')parent.onclick = function () {console.log('parent')}let child = document.getElementById('child')child.onclick = function (ev) {var e = ev || window.event// console.log(e)console.log('child')stopPropagation(e)}function stopPropagation (e) {if (e.stopPropagation) {e.stopPropagation()} else {e.cancelBubble = true}}</script>

结果如下:
在这里插入图片描述
可以通过运行结果来看,事件冒泡成功被阻止了。

看到这里,相信小伙伴们可能会觉得事件冒泡很麻烦,还需要写个事件阻止冒泡行为。但凡事都有双刃剑,事件冒泡同时给我们带来的还有事件委托这一减少DOM操作的神器。

2、事件委托(事件代理)

2.1 概念

事件委托,首先按字面的意思就能看你出来,是将事件交由别人来执行,再联想到上面讲的事件冒泡,是不是想到了?对,就是将子元素的事件通过冒泡的形式交由父元素来执行。下面经过详细的例子来说明事件委托:

2.2 for循环遍历给每个li添加事件

在开发的时候可能会遇到这种情况:如给ul下的每个li都加一个事件,你可能会通过遍历来给每个栏目添加事件:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><ul id="parentUl"><li>我是子元素</li><li>我是子元素</li><li>我是子元素</li></ul><script>var ul = document.getElementById('parentUl'),li = ul.getElementsByTagName('li')for (var i = 0; i < li.length; i++) {li[i].onclick = function () {alert(this.innerHTML)}}</script>
</body></html>

在这里插入图片描述
这种方式来添加事件固然简单,但是需要多次操作DOM,如果有100、1000个同级的元素需要添加事件,这种方式就不可取了。

2.3 利用事件代理给li添加事件

事件委托是利用事件的冒泡原理来实现的,比如我们平时在给ul中的li添加事件的时候,我们都是通过for循环一个个添加,如果li很多个的话,其实就有点占内存了,这个时候可以用 事件代理来优化性能,

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head><body><ul id='ulid' onclick='clickFunc()'><li>1个li</li><li>2个li</li><li>3个li</li><li>4个li</li><li>5个li</li></ul><script>function clickFunc (ev) {var ev = ev || window.eventconsole.log(ev)var oLi = ev.srcElement || ev.targetif (oLi.nodeName.toLowerCase() == 'li') {alert(oLi.innerText)}}</script>
</body></html>

结果如下:
在这里插入图片描述


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

相关文章

UML与流程图

UML简介 UML&#xff08;Unified Modeling Language&#xff0c;统一建模语言&#xff09;是一种用于软件系统分析与设计的标准化建模语言。它提供了一套丰富的图形符号和规则&#xff0c;可用于描述系统的结构、行为和交互&#xff0c;帮助开发人员、设计师和利益相关者之间进…

“红帽认证”考试,这些知识点必须掌握

话不多说直接上干货&#xff0c;本篇文章适用于备考Linux红帽认证的同学。 man命令中常用按键以及作用 man命令中帮助信息的结构以及意义 reboot命令reboot命令用于重启系统&#xff0c;输入该命令后按回车键执行即可。 [rootlinuxprobe ~]# reboot poweroff命令poweroff命令…

节省时间又方便,这些APP让你工作事半功倍

节省时间又方便&#xff0c;这些APP让你工作事半功倍 软件一&#xff1a;半导体工具箱 1.芯片量产价格查询 包含仿真版图工具、快速封口查询工具、流片查询工具。 2.科学计算器 包含长度换算、压力换算、重量换算、面积换算、功率换算计算、做功、能量和热量换算。 3.组件…

为什么Android操作系统是基于LInux的开源操作系统,却使用java开发

Android是基于linux的开源操作系统&#xff0c;而linux是使用标准C语言开发的操作系统&#xff0c;所以android底层驱动以及操作系统内核使用C语言以及汇编开发的。 但是 Android操作系统本身是使用Java开发&#xff0c;并使用JNI调用本地的C语言库&#xff0c;实现操作系统底…

安卓是一个独立的操作系统

有一种说法是安卓是linux的发行版&#xff0c;因为它也是基于Linux内核的&#xff0c;但是仔细想想觉得不是这样。 理由如下&#xff1a;1操作系统按照内核分类的意义不大&#xff0c;按照系统的应用程序格式和api划分更好。2安卓使用了虚拟机。 安卓的确是使用了linux内核&am…

安卓系统的发展历程?

程序员宝藏库&#xff1a;GitHub - Jackpopc/CS-Books-Store: 你想要的计算机经典书籍&#xff0c;这里都有&#xff01; 作为目前手机市场份额最高的操作系统&#xff0c;Android已经达到一种可以决定一家手机公司命运的程度。 华为在受到GMS生态限制之后&#xff0c;通过深厚…

安卓系统 国内谷歌服务器,在国内使用搭载安卓原生态系统谷歌手机,会是一种什么体验?...

我们讨论这个话题&#xff0c;就不得不讨论另外一个话题&#xff0c;那就是在中国区域销售的安卓手机&#xff0c;都是基于安卓系统进行深度定制开发的&#xff0c;而且在国内也不用GMS服务&#xff0c;UI系统深度定制参与到了安全隐私、牵扯到了很多深度权限的研发&#xff01…

android在国内如何盈利,安卓系统在中国靠什么盈利?

为何谷歌的安卓系统没有在中国收取费用&#xff0c;依靠什么进行盈利&#xff1f; 谷歌的安卓系统在中国没有收费最主要的因素与两点有关&#xff1a; 首先是谷歌安卓系统的发展之初的定位&#xff0c;当时移动端的竞争压力相当巨大。苹果的iOS系统、塞班系统、微软的Windows M…