[Day 17] JS - 冒泡事件 (Event Bubbling)

前言

延续昨天的事件监听,一开始花了满多时间在认识各个事件的使用方式,特别在後续专案实作上,认识更多的执行方式。不过对於基础观念不花费心力来理解它,永远就是会弄不清楚,其中冒泡事件就是其中之一,从刚开始进入 JS 实作时,总是会不太清楚为什麽这里要下 event.stopPropagation(),总以为是必须要写上的,直到学习到冒泡事件 (Event Bubbling)才知道用意啊~

学习资源分享

  1. JavaScript DOM Tutorial #10 - Event Bubbling,以ul > li的列表来介绍绑定监听事件,并以情况说明会发生什麽问题,该如何「捕获」或「冒泡」特性来修正,藉此也可以深刻记得未来在做类似的功能时,要注意哪些地方。
  2. JavaScript Event Capture, Propagation and Bubbling - #JavaScript30 25/30,JavaScript30 的相关课程,影片不长但详细地说明冒泡事件 (Event Bubbling)的运作机制。

从监听事件开始

  • 建立监听事件,主要有以下参数
    • 选择要出现的事件:click,hover,hide,mouseover...
    • 中间为匿名 function,用来放入主要要做的功能
    • 布林值:由 Boolean 决定事件是以「捕获」或「冒泡」机制执行,若不指定则预设为「冒泡」
var button = document.querySelector('.btn');
button.addEventListener('click',function(e){
  alert('Hello this is button');
},false)

JS中事件的三个阶段

  1. 捕获阶段(Capture Phase):DOM 的事件会从(window) 开始往下寻找目标 (target)。是一个找寻过程
  2. 目标阶段(Target Phase):到达事件目标(找到元素),就是到了目标阶段。
  3. 冒泡阶段(Bubbling):由事件目标依序向外传递,过程中触发各别元素的监听事件。(逐层往上传递,直到整个网页的根节点,也就是 document->Window。)
  • 透过下图,来更了解三阶段:
    • 捕获:从window逐步往下找寻目标。
    • 目标:找到目标为<td>
    • 冒泡:<td>被点击时,事件会冒泡往上执行。

要如何控制捕获或冒泡?

  • 透过addEventListener方法的最後一个参数phase(阶段)来决定
    • false(冒泡事件,Event Bubbling)- 从指定元素往外层找
      • 当最内部的元素被触发事件时,会先执行自己本身的事件处理函式,然後才会执行上层父母元素的事件处理函式。
    • true(捕获事件,Event Capuring)- 从最外面找到指定元素
      • 当最内部的元素被触发事件时,会先从最外围的事件处理函式执行,依序到最後才是执行自己本身的处理函式。
    • 如果预设没写的话,就是false,也就是预设使用事件冒泡(bubbling)

js事件处理

事件冒泡会产生怎麽样的行为

  • 事件点击後,会一直冒泡上去

以例子来说明

  • 建立具有父层、子层关系的3个box
    • 并於3个div,都建立监听事件=>点击时,印出字样box-3 is clicked

冒泡事件就是:

  • 当点击box-3(最内层元素),会往上触发父层的元素
    • 可以看到3->2->1被触发
  • 当点击box-2
    • 2->1被触发
  • 当点击box-1,就会只有box-1触发,并印出box-1 is clicked!

  <div id="box-1">
    <h2>box-1</h2>
    <div id="box-2">
      <h2>box-2</h2>
      <div id="box-3">
        <h2>box-3</h2>
      </div>
    </div>
  </div>
  
  <script>
    $(function () {
      // 点击3时,2也会触发(这就是冒泡事件的特性),所以必须要停止冒泡行为,否则它会一直往上触发。
      //他的顺序是固定的3->2->1,从最里面开始

      $('#box-3').click(function () {
        console.log("box-3 is clicked!");
      });
      $('#box-2').click(function () {
        console.log("box-2 is clicked!");
      })
      
      $('#box-1').click(function () {
        console.log("box-1 is clicked!");
      })


    })


  </script>

如何阻止事件冒泡

  • 透过阻止冒泡事件,确实只执行所点击的元素。所以只要在该监听事件函式内加入:e.stopPropagation()
    • 以下,选取到#box-3,并设定阻止冒泡的行为发生,就可以发现他只会出现 box-3 is clicked!
   $('#box-3').click(function (event) {
        //阻止冒泡的行为发生
        event.stopPropagation();
        console.log("box-3 is clicked!");
      });

参考资料:
[第七周] DOM - 事件传递机制:捕获与冒泡、事件代理
重新认识 JavaScript: Day 14 事件机制的原理
DOM 的事件传递机制:捕获与冒泡


<<:  Day03 - Amazon ECS Anywhere 基础说明与建置(上)

>>:  Rust-资料型别-复合型别

DAY29-ASP.NET网页切换导向及状态管理-趴水

ASP.NET网页切换导向及状态管理-趴水 今天来做做看 在网页输入资料後 按下按钮 可以将资料导向...

[Day30] 套件统整 && 简单的完赛感言

那今天主要是让读者知道 Rust 有哪些套件 该从哪里下手 我尽量把我知道的都写出来 网页前端 WA...

Day 6 Capsule的应用(下)

前言 今天把昨天讲的论文做一个总结,明天就要开始介绍attention了 A2D dataset 这...

[Day-12] R语言 - K - prototype 实作 ( K - prototype in R.Studio)

您的订阅是我制作影片的动力 订阅点这里~ 影片程序码 ## k prototype #### lib...