JavaScript事件触发过程底层原理

在Web开发中,JavaScript的事件处理是一个至关重要的主题。理解事件触发的过程以及掌握事件代理是成为优秀前端工程师的关键之一。本文将深入探讨JavaScript中事件的触发过程以及事件代理的概念、优势和使用场景。


首先我们有着这样三个互相嵌套的div,a,b,c,a为红色,b为蓝色,c为黑色。 接着给a,b,c都添加上点击事件

事件触发过程

js 复制代码
 a.addEventListener("click",()=>{
        console.log('a被点击');
    },false)

    b.addEventListener("click",(event)=>{
        console.log('b被点击');
    },false)

    c.addEventListener("click",(event)=>{
        console.log('c被点击');
    },false)

显然此时点击最内层的c三个点击事件都会被触发。但是!!!

这三个事件触发的顺序是怎么样的以及为什么是这样

首先告诉大家

事件触发的过程是c,b,a,那么为什么是这样一个过程呢?

背后的底层原理

在JavaScript中的事件触发过程分为捕获过程和冒泡过程,这两个过程构成了事件传播的整体流程。

  1. 捕获过程:window往事件触发处传播。
  2. 目标触发: 传播到事件目标处,触发注册的事件处理函数。
  3. 冒泡过程: 从事件触发处往window上传播。当遇到注册的冒泡事件时,触发相应的处理函数。这个过程是默认的事件触发方式。 点击c整个事件流的传播过程是这样的:
  4. window->c->b->a捕获过程
  5. a->b->c->window冒泡过程 a,b,c绑定的事件就在冒泡过程依次被触发 需要注意的是,捕获事件和冒泡事件是互斥的,在捕获事件内触发了就不会在冒泡事件内触发。而且在JavaScript中,默认所有事件都只在冒泡过程中触发。如果想要在捕获过程中触发,可以通过修改addEventListener的第三个参数来实现

这个值默认是false,当为false时就会在冒泡过程时触发,如果设置为true就会在捕获过程时触发。

阻止默认行为

在事件处理中,有时候需要阻止事件的默认行为,比如阻止链接的跳转或表单的提交。为此,可以使用以下方法:

  1. event.stopPropagation() 该方法可以阻止事件流的传播,即停止事件在捕获或冒泡阶段的传递。
  2. event.stopImmediatePropagation() 除了阻止事件流传播外,该方法还能阻止同一容器上绑定的其他相同事件的执行。
js 复制代码
   b.addEventListener("click",(event)=>{
        console.log('b被点击');
        event.stopPropagation()
    },true)

如果设置b身上绑定的事件在捕获过程时触发并在触发的事件内部添加event.stopPropagation(),此时点击c就会输出如下

此时在捕获过程由window向c传播,c------>b然后此时b事件触发并且阻断事件流的传播。至此事件流的传播就结束了。

这两个方法之间的区别在于,event.stopImmediatePropagation()还能够阻断自身的事件传播。当我们在c身上添加两个点击事件并给第一个点击事件加入 event.stopPropagation();时,此时我们点击c就会发现

js 复制代码
    c.addEventListener("click",(event)=>{
        console.log('c被点击');
        event.stopPropagation();
    },false)

    c.addEventListener("click",(event)=>{
        console.log('c被点击2');
    },false)

会有着两次输出。如果此时把第一个点击事件中的event.stopPropagation();换成event.stopImmediatePropagation()我们就会发现 只有着一次输出了,这就是因为event.stopImmediatePropagation()还会阻断自身事件流的传播,不过需要注意的是,写有event.stopImmediatePropagation()的点击事件需要在另外一个点击事件的上面才能够被阻断。

这两个方法的灵活运用可以有效地控制事件的传播行为。

相关推荐
不在逃避q1 小时前
Trae/Vs Code/Cursor命令行无法跑npm命令
前端·arcgis·npm
夏殇之殁1 小时前
包中创建自定义列表项。 . 使用自定义列表项进行数据绑定 . 将天气预报数据保存到本地内存表,通过LiveBindings进行显示。 ...
服务器·前端·javascript
The Chosen One9851 小时前
高进度算法模板速记(待完善)
java·前端·算法
陈随易1 小时前
MoonBit抓包模块pcap,查看电脑的每一次联网通信
前端·后端·程序员
新中地GIS开发老师2 小时前
WebGIS开发学生作品|低空航天管理与航线规划系统
前端·javascript·webgis·三维gis开发
用户059540174463 小时前
大模型对话记忆持久化踩坑实录:用 Playwright 自动化测了 300 次,终于揪出会话丢失的真凶
前端·css
丙氨酸長鏈3 小时前
Web前端入门第 问:JavaScript 一个简单的 IndexedDB 数据库入门示例
前端·javascript·数据库
kyriewen4 小时前
面试官让我手写虚拟列表——AI生成的版本,快速滚动几下就白屏了
前端·javascript·面试
IT_陈寒4 小时前
Vite热更新失效?你可能漏了这个配置
前端·人工智能·后端
梅孔立4 小时前
两种免费的翻译API调用方式详解 - Edge官方API与个人缓存服务
前端·缓存·edge