首页 > 其他分享 >事件冒泡

事件冒泡

时间:2023-10-10 14:56:13浏览次数:43  
标签:事件处理 元素 冒泡 div3 event 事件

一个问题

如果有下面一段代码:

  1. 在 HTML 中,定义了嵌套的 3 个 <div/>,ID 分别为 div1、div2、div3。
  2. 在 JavaScript 中定义一个点击事件处理函数,打印当前执行事件元素的 id。
  3. 把事件处理函数分别注册到这 3 个 div 中。

这个时候,如果点击最里边的 div3 元素,你猜代码的输出结果是什么?

// html:
<div id="div1">
  div1
  <div id="div2">
    div2
    <div id="div3">div3</div>
  </div>
</div>;

// javascript:

function handleClick(event) {
  console.log(event.currentTarget.id);
}
for (let i = 1; i <= 3; i++) {
  let div = document.getElementById(`div${i}`);
  div.addEventListener("click", handleClick);
}



选项 
A. div3
B. div3, div2, div1

答案是:B。 为什么结果会是这样呢?这得从 JavaScript 的事件冒泡机制说起。

什么是事件冒泡机制

事件冒泡机制是说,在给某个 DOM 元素设置了事件监听器之后,例如鼠标点击事件,在触发事件时,浏览器不仅仅执行该元素的事件处理函数,还会顺着 DOM 树的结构,一级一级的往上查找,是不是有父级元素注册了相同的事件监听器,如果有的话,还会执行父级元素的事件处理函数,直到 <html /> 根元素为止。

在上边的例子中,点击了 div3 元素之后:

  • 先执行了 div3 的点击事件处理函数,此时 event.currentTarget 是 div3 这个元素,打印出它的 id 为 div3。
  • 接着浏览器会查找上级元素 div2 有没有点击事件监听,结果有,那么就执行了它的处理函数打印出 div2。
  • 同理,打印出最外层的 div1 之后,就再没有点击事件监听了,这个时候事件才停止冒泡了。

阻止事件冒泡机制

事件冒泡机制会给开发中带来意想不到的结果,要阻止它也很简单,只需要在事件处理函数中,调用事件参数的 stopPropagation() 方法,这样事件在当前元素处理完成之后就结束了,不会再查找父级组件相同的事件监听了。

event.stopPropagation();

如果我们在之前的例子中,事件处理函数里,加上这段代码,那么,再点击最里边的 div3,就只会打印出 div3 了:

function handleClick(event) {
  event.stopPropagation();
  console.log(event.currentTarget.id);
}

对于一些老的浏览器,例如 IE9 以下,如果要阻止事件冒泡,需要设置 event 参数的 cancelBubble 属性为 true:

event.cancelBubble = true;

这样也就阻止事件冒泡了。如果以后遇到了同时触发了多个事件的情况,可以先想一下是不是事件冒泡机制捣的鬼,如果是就把它停止。

转载:JavaScript事件冒泡机制 - 峰华前端工程师 (zxuqian.cn)

标签:事件处理,元素,冒泡,div3,event,事件
From: https://www.cnblogs.com/shangeg/p/17754678.html

相关文章

  • 【转】JS事件捕获和事件冒泡
    DOM事件流(eventflow)存在三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。事件捕获(eventcapturing):当鼠标点击或者触发dom事件时(被触发dom事件的这个元素被叫作事件源),浏览器会从根节点=>事件源(由外到内)进行事件传播。事件冒泡(dubbedbubbling):事件源=>根节点(由内到外)......
  • fastadmin框架input下拉选框值改变时的事件
      效果:选择基地时自动填充负责人和手机号,并给地块选框赋值所选基地的参数(筛选出该基地的地块) ......
  • C#应用 - 事件总线
    目录前言1,简介2,设计2.1设计思路2.2设计实现2.2.1IEventData2.2.2EventBus2.2.3用起来3,问题3.1起缘3.2改造3.3用起来前言发布订阅模式很常见,每个发布者和订阅者之间都搭建了一条小线路,随着功能越来越多,事件和委托就会满天飞,就像私拉电线的蜘蛛网一样。这时候可能需要一种......
  • fgui 点击事件的 pos 怎么转化为 Cocoscreator 世界坐标
    对于fgui的点击事件e:e.pos并不是屏幕坐标e.pos是相对于Canvas的一个坐标e.pos几乎是Canvas下的ui空间世界坐标。又有:e.pos使用的坐标系:x轴向右,y轴向下。Canvas使用的坐标系:x轴向右,y轴向上。因此:import{Event}from"fairygui-ccc370";//...privat......
  • 基于Spring事件驱动模式实现业务解耦
    事件驱动模式举个例子......
  • 输入若干个数值存入数组中,采用冒泡算法进行升序或降序排序
    [12:38:09root@centos8~]#bashsort.shbeforesort:1475626459133973060324422175901602255661082520888121022092421146668557255975852542867817400aftersort:3060328678264592442220888175901740016022147561339711466108259758924272......
  • uni自定义onBackPress事件
    onBackPress函数return非true以外的值都会执行默认的返回行为,只有returntrue才不会执行返回事件,所以在执行自定义事件时一定要返回truedata(){return{isConfirm:false,//处理返回逻辑};},methods:{onBackPress()......
  • 10.3 调试事件转存进程内存
    我们继续延申调试事件的话题,实现进程转存功能,进程转储功能是指通过调试API使获得了目标进程控制权的进程,将目标进程的内存中的数据完整地转存到本地磁盘上,对于加壳软件,通常会通过加密、压缩等手段来保护其代码和数据,使其不易被分析。在这种情况下,通过进程转储功能,可以将加壳程序的......
  • 10.2 调试事件获取DLL装载
    理解了如何通过调试事件输出当前进程中寄存器信息,那么实现加载DLL模块也会变得很容易实现,加载DLL模块主要使用LOAD_DLL_DEBUG_EVENT这个通知事件,该事件可检测进程加载的模块信息,一旦有新模块被加载或装入那么则会触发一个通知事件,利用该方法并配合磁盘路径获取函数则可很容易的实现......
  • 10.3 调试事件转存进程内存
    我们继续延申调试事件的话题,实现进程转存功能,进程转储功能是指通过调试API使获得了目标进程控制权的进程,将目标进程的内存中的数据完整地转存到本地磁盘上,对于加壳软件,通常会通过加密、压缩等手段来保护其代码和数据,使其不易被分析。在这种情况下,通过进程转储功能,可以将加壳程序的......