浏览器中的事件冒泡,事件捕获,事件委托

事件冒泡

事件冒泡(dubbed bubbling):当一个元素接收到事件的时候,会把他接收到的事件传给自己的父级,一直到 window。

会冒泡的事件有:

  • 鼠标事件:click, dblclick, mousemove,
  • 键盘事件:keyup, keydown
  • 表单事件:input, change, submit
  • 触摸事件:drag, dragstart, dragend

不会冒泡的事件有:

  • 焦点事件:focus, blur

  • 鼠标事件:mouseenter, mouseleave

  • 媒体事件:play, pause, ended

    事件源 =>根节点(由内到外)进行事件传播。

给三个盒子依次绑定点击事件,当点击最小small盒子的时候,会依次触发父级元素的点击事件。

有些时候我们不希望产生事件冒泡,所以可以 在子事件中加入e.stopPropagation() 取消冒泡

事件捕获

事件捕获(event capturing): 当鼠标点击或者触发dom事件时(被触发dom事件的这个元素被叫作事件源),浏览器会从根节点 =>事件源(由外到内)进行事件传播。

事件捕获与事件冒泡是比较类似的,最大的不同在于事件传播的方向。

click small box

一个事件的完整生命周期分为三个阶段:

  1. 捕获阶段 (Capturing Phase): 事件从windowdocument开始,向下传播到目标元素。
  2. 目标阶段 (Target Phase): 事件到达并被目标元素本身处理。
  3. 冒泡阶段 (Bubbling Phase): 事件从目标元素向上回溯到windowdocument注意: 并不是所有事件都会冒泡(例如 focusblurmouseentermouseleave 等事件默认不冒泡)。

事件委托

事件委托也称为事件代理。就是利用事件冒泡,把子元素的事件都绑定到父元素上。如果子元素阻止了事件冒泡,那么委托就无法实现。

应用场景:1000个button需要注册点击事件

如果循环给每个按钮添加点击事件,那么会增加内存损耗,影响性能

此时可以给button的父元素添加点击事件

这时相当于每个按钮都绑定了点击事件

优点:

替代循环绑定事件的操作,减少内存消耗,提高性能。比如: 在table上代理所有td的click事件。 在ul上代理所有li的click事件。

简化了dom节点更新时,相应事件的更新。比如: 不用在新添加的li上绑定click事件。 当删除某个li时,不用移解绑上面的click事件。

缺点:

  1. 事件委托基于冒泡,对于不冒泡的事件不支持。
  2. 层级过多,冒泡过程中,可能会被某层阻止掉。
  3. 理论上委托会导致浏览器频繁调用处理函数,虽然很可能不需要处理。所以建议就近委托,比如在table上代理td,而不是在document上代理td。

事件对象

只有在事件处理程序期间,event对象才会存在,一旦事件处理程序执行完成,event对象就会被销毁

event对象里需要关心的两个属性:

  1. target:target永远是被添加了事件的那个元素;

  2. eventPhase:调用事件处理程序的阶段,有三个值

    1. 捕获阶段;
    2. 处于目标;
    3. 冒泡阶段;

preventDefault与stopPropagation

preventDefault:比如链接被点击默认会导航到其href指定的URL, <input type="checkbox"> 默认会切换选中状态。

js 复制代码
const myForm = document.getElementById('myForm');

  myForm.addEventListener('submit', function(event) {
    // 阻止表单的默认提交行为
    event.preventDefault();

    const inputValue = document.getElementById('myInput').value;
    // 你可以在这里使用 AJAX 将 inputValue 发送到服务器,
    // 或者进行客户端验证等
    console.log('表单提交被阻止,输入的值是:', inputValue);
    alert('表单提交被阻止,请检查控制台。');
  });

stopPropagation:立即停止事件在DOM层次中的传播,包括捕获和冒泡事件;但是同一节点上的其他listener还会被执行,如果要同一级的listener也不执行,使用stopImmediatePropagation()

引用

【面试题】对JS中的事件冒泡、事件捕获、事件委托的理解_面试问到事件冒泡和事件捕获怎么说-CSDN博客

相关推荐
倔强青铜三19 分钟前
苦练Python第58天:filecmp模块——文件和目录“找不同”的利器
人工智能·python·面试
倔强青铜三21 分钟前
苦练Python第59天:tempfile模块,临时文件自动删!再也不用手动清理到怀疑人生
人工智能·python·面试
彩旗工作室25 分钟前
用 Supabase 打造统一认证中心:为多应用提供单点登录(SSO)
服务器·前端·数据库
Q741_14739 分钟前
C++ 位运算 高频面试考点 力扣 371. 两整数之和 题解 每日一题
c++·算法·leetcode·面试·位运算
EveryPossible39 分钟前
第一版代码
前端·javascript·css
ObjectX前端实验室1 小时前
【图形编辑器架构】渲染层篇 — 从 React 到 Canvas 的声明式渲染实现
前端·计算机图形学·图形学
java水泥工1 小时前
基于Echarts+HTML5可视化数据大屏展示-智慧消防大屏
前端·echarts·html5
杨超越luckly1 小时前
HTML应用指南:利用POST请求获取全国索尼体验型零售店位置信息
前端·arcgis·html·数据可视化·门店数据
ObjectX前端实验室1 小时前
【图形编辑器架构】节点树篇 — 从零构建你的编辑器数据中枢
前端·计算机图形学·图形学
ikun778g2 小时前
uniapp设置安全区
前端·javascript·vue.js·ui·uni-app