iT邦幫忙

2021 iThome 鐵人賽

DAY 24
0
Modern Web

舌尖上的JS系列 第 24

D24 - 走!去瀏覽器偷聽 Capturing & Bubbling

  • 分享至 

  • xImage
  •  

前言

這篇介紹 DOM Event Listener - 事件監聽 (總覺得監聽這個翻譯很有抓姦的畫面感?!)

實作:利用捕獲機制設計燈泡漸進式的關燈效果 💡💡💡

所謂的監聽事件

昨天的 cookie generator 點擊按鈕時產生餅乾,使用的是 事件綁定,也就是在 html 的按鈕標籤加上屬性 onclick = 'addCookie()' ,這種直接寫在 html 上是比較舊式的寫法,JavaScrip 和 html 寫在一起看起來比較不簡潔以外,也容易有XSS 攻擊事件的風險,因此後來新的寫法是透過 監聽事件 addeventListener 做綁定。
(兩種方法都練習看看過才有更深刻的感覺~)

但不管是哪種寫法,在 DOM 上的監聽事件都必須設定三個主軸:

  1. Event Target 監聽的對象:ex. 按鈕
  2. Event 監聽的事件:ex. 點擊
  3. Event Handler 監聽事件發生時的應對動作,ex. 產生餅乾

那我們監聽的對象是誰呢?

主要的目標對象是 element、document、window,但也可以設定在其他如 XMLHttpRequest、AudioNode、 AudioContext 上。

瞭解什麼是監聽事件後,就來研究語法吧!

綁定監聽事件 AddEventListener

EventTarget.addEventListener(event, eventHandler, boolean)

第一個參數 Event

內建的監聽事件很多,像是滑鼠的點擊、移動、聚焦,各種使用者在瀏覽器上可以進行的行為都有對應的事件,詳細可以到 MDN 列出的表格查看

與舊式事件綁定寫法不同,事件名稱不需要加上 on
ex. 點擊事件寫在 html 是 onclick,但在事件監聽器是 click

第二個參數 Event Handler

事件觸發後要執行的程式,可以是匿名或具名函式。

第三個參數 決定 捕獲 Capturing | 冒泡 Bubbling

第三個參數為 boolean 值,決定監聽事件是要綁定在捕獲階段還是冒泡階段上。

  • false: 預設值,表示將監聽事件綁定在 冒泡階段 Bubbling Phase
  • true:表示將監聽事件綁定在 捕獲階段 Capturing Phase

詳細的解釋推薦看這篇 事件迴力鏢 - 捕獲與冒泡,接下來讓我用變色圈圈告訴你差別~

實作:大中小圈圈變色方向

設置三個分別為大中小的圈圈,每個圈圈綁定點擊時會亮起各自的背景色,大概的 html 階層如下。
變色上為了讓傳遞的效果明顯一點,加上 setTimeout 設定時間差異,但以下解釋先省略這部分,主要介紹綁定在冒泡階段與綁定在捕獲階段的差異。

// 圈圈層層包裹
  <div class='big'>
    <div class='middle'>
      <div class='small'></div>
    </div>
  </div>

Bubbling 冒泡傳遞

將點擊事件綁定在冒泡階段

// 綁定事件的第三個參數都設為 false 
bigCircle.addEventListener("click", changeBlue, false);  // 點擊大圈圈背景變深藍 
middleCircle.addEventListener("click", changePurple, false); // 點擊中圈圈背景變紫色
smallCircle.addEventListener("click", changeLightblue, false); // 點擊小圈圈背景變淺藍

動作:點擊小圈圈
結果:小圈圈先亮 -> 中圈圈亮 -> 大圈圈亮

可以看到冒泡階段的傳遞方向,是由內層的標籤一路往外傳,當小圈圈收到點擊時,會再往外傳到中圈圈,中圈圈再往外傳到大圈圈,一直到最外層的 window 為止。

Carturing 捕獲傳遞

將點擊事件綁定在捕獲階段

// 綁定事件的第三個參數都設為 false 
bigCircle.addEventListener("click", changeBlue, true);  // 點擊大圈圈背景變深藍 
middleCircle.addEventListener("click", changePurple, true); // 點擊中圈圈背景變紫色
smallCircle.addEventListener("click", changeLightblue, true); // 點擊小圈圈背景變淺藍

動作:點擊最小圈圈
結果:大圈圈先亮 -> 中圈圈亮 -> 小圈圈亮

順序跟剛剛不同!因為捕獲階段的順序是從最外層的標籤傳到最內層,所以大圈圈會先經歷捕獲階段,因此先捕捉到點擊事件亮起背景色,而小圈圈是整個捕獲階段的終點,最後才收到點擊事件。

Reference

重新認識 JavaScript: Day 15 隱藏在 "事件" 之中的秘密
DOM 的事件傳遞機制:捕獲與冒泡
MDN

結語

所以囉,可以透過傳遞的方向差異製造不同的效果,一開始的燈泡就是將點擊事件階段綁定在 捕獲階段 capturing phase,所以當點擊燈泡時,黑色燈光是從外暗到內!
每次學到新的語法就迫不及待試試可以做出什麼效果,覺得開心 ≧ω≦


上一篇
D23 - 走!去瀏覽器用 create & append 加餐
下一篇
D25 - 走!去瀏覽器吃餅乾 yummy yummy!
系列文
舌尖上的JS30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
南國安迪
iT邦新手 3 級 ‧ 2021-10-09 19:11:48

請問今天是吃什麼呢?
/images/emoticon/emoticon34.gif

0
Chiahsuan
iT邦新手 4 級 ‧ 2021-10-09 20:24:14

圈圈的示範太棒了(一圖勝萬語)~~~而且配色好好看/images/emoticon/emoticon24.gif

我要留言

立即登入留言