花潮论坛

搜索
热搜: 活动 交友 discuz
查看: 15|回复: 1

理解JS事件冒泡

[复制链接]
  • TA的每日心情
    奋斗
    2026-3-10 12:57
  • 签到天数: 1755 天

    [LV.Master]伴坛终老

    3139

    主题

    13万

    回帖

    28万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮帅哥鼠牛虎兔龙蛇马羊猴鸡狗猪多彩人生星月交辉奔放热烈海样胸怀春风拂面火热情怀优雅迷人神秘浪漫相遇之美鹰傲苍穹花好月圆紫色情节飞龙在天王者至尊大将风范音画大师天籁妙音共看流星风雨同行我心永远幸福快乐喜乐安康侠骨柔肠心想事成开朗大方花潮管理

    发表于 2026-3-10 12:57 | 显示全部楼层 |阅读模式

    请马上登录,朋友们都在花潮里等着你哦:)

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x

    当 html 元素彼此间存在“血亲关系”,即它们层层嵌套,那么,最里层的元素发起人机交互动作时,外层的任意一层都可以接收到这个事件。可以将层层嵌套的元素想象成俄罗斯套娃:你戳一下最里层的娃娃,它外面的每一个娃娃都可以依次感知到被戳了一下。这就是所谓的“冒泡”:事件被触发后从触发点外溢,这个事件就像涟漪一样被传输到存在“直系亲属”关系的所有元素,只要它们原意监听。

    网页“直系关系”示意图谱:

    window → document → html → body → div(或其他元素)

    试看下面的代码,重点理解 html 代码:四个 div 盒子层层嵌套,它们是“四代同堂”的直系亲属关系——

    <style> .ttDiv { margin: auto; width: 40vw; aspect-ratio: 1 / 1; border: 1px solid gray; display: grid; place-items: center; position: relative; } .ttDiv::after { content: attr(data-counter); position: absolute; left: 10px; top: 5px; } .outer1 { width: 40vw; margin-top: 100px; } .inner1 { width: 30vw; } .inner2 { width: 20vw; } .inner3 { width: 10vw; } </style> <div id="div1" class="ttDiv outer1" data-counter="0"> <div id="div2" class="ttDiv inner1" data-counter="0"> <div id="div3" class="ttDiv inner2" data-counter="0"> <div id="div4" class="ttDiv inner3" data-counter="0"></div> </div> </div> </div> <script> // 点击计数器函数 const clicking = (element) => { let counter = element.dataset.counter * 1 + 1; element.dataset.counter = counter; } // 获取所有的 .ttDiv 盒子 const ttDivs = document.querySelectorAll('.ttDiv'); // 盒子被点击时触发计数 ttDivs.forEach(ttdiv => { ttdiv.onclick = () => clicking(ttdiv); }); </script>

    这组代码为每一个 div 设置了::after伪元素,用以展示被点击的次数。JS 代码设计了一个计数器函数:元素如果被点击则计数器加 1,然后每一个 div 都监听点击事件,该事件如果被触发则执行计数器函数。

    理解冒泡事件,可以点击代码栏右上角“预览”按钮进入预览页面,点击不同层级的 div 元素,观察计数器的变化。

    如你所见:冒泡是从里往外发起。如果点击的不是最里层的,那么,不被点击的里层 div 计数器不会发生变化。

    网页元素冒泡路径示意图:

    divs(或其它元素)→ body → html → document → window

    冒泡如果不人为阻止,它一直会往外冒,直至“直系亲属”的最后一个成员。换言之,上述“四代同堂”的 div 之外,如果还有其它的属于它们祖先的 div 或是其它容器盒子,都会接收到冒泡事件,直至DOM“族谱”的根(window对象)才会停止。

    阻止冒泡指特定元素的事件私有化,不允许外层的“直系亲属”捕获相关事件。这时候,可以在特定元素的指定事件(例如点击事件)中加入 event.stopPropagation()(中断传播)加以实现。前面的代码示例,每一个 div 都有 id 标识符,JS 中的元素点击事件代码可以通过识别目标的 id,如果与指定点击事件要阻止冒泡的 div 的 id 相匹配就阻隔事件的冒泡行为。可以这样改进 div 的点击事件:

    // 盒子被点击时触发计数,阻止 div4 的点击行为冒泡 ttDivs.forEach( ttdiv => { ttdiv.onclick = (event) => { if (event.target.id === 'div4') event.stopPropagation(); clicking(ttdiv); } });

    这么一来,最里层的 div 被点击时,只有它自己的计数器发生变化,外层所有元素都不再能够捕获到点击事件。而其长辈 div 没有受到限制,它们的点击事件仍然会冒泡。

    评分

    参与人数 1威望 +30 金钱 +60 经验 +30 收起 理由
    杨帆 + 30 + 60 + 30 匠心独运,细节精致入微!

    查看全部评分

  • TA的每日心情
    奋斗
    2026-3-10 12:14
  • 签到天数: 472 天

    [LV.9]以坛为家II

    351

    主题

    3549

    回帖

    2万

    积分

    版主

    Rank: 7Rank: 7Rank: 7Rank: 7Rank: 7Rank: 7Rank: 7

    花潮帅哥鼠牛虎兔龙蛇马羊猴鸡狗猪多彩人生鹰傲苍穹飞龙在天王者至尊大将风范花潮版主

    发表于 2026-3-10 15:05 | 显示全部楼层
    本帖最后由 杨帆 于 2026-3-10 15:06 编辑

    理解JS事件冒泡很重要,但理解起来很抽象,感谢马老师深入浅出、言简意赅、通俗易懂的讲授
    ★青春是一个人的精神生命,奋斗是一个人最大的体面,学习是一个人最美的姿态。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    小黑屋|手机版|Archiver|服务支持:DZ动力|huachaowang.com Inc. ( 蜀ICP备17032287号-1 )

    GMT+8, 2026-3-10 18:15 , Processed in 0.070618 second(s), 25 queries .

    Powered by Discuz! X3.4

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表