這篇介紹 DOM Event Listener - 事件監聽 (總覺得監聽這個翻譯很有抓姦的畫面感?!)
實作:利用捕獲機制設計燈泡漸進式的關燈效果 💡💡💡
昨天的 cookie generator 點擊按鈕時產生餅乾,使用的是 事件綁定,也就是在 html 的按鈕標籤加上屬性 onclick = 'addCookie()'
,這種直接寫在 html 上是比較舊式的寫法,JavaScrip 和 html 寫在一起看起來比較不簡潔以外,也容易有XSS 攻擊事件的風險,因此後來新的寫法是透過 監聽事件 addeventListener 做綁定。
(兩種方法都練習看看過才有更深刻的感覺~)
但不管是哪種寫法,在 DOM 上的監聽事件都必須設定三個主軸:
主要的目標對象是 element、document、window,但也可以設定在其他如 XMLHttpRequest、AudioNode、 AudioContext 上。
瞭解什麼是監聽事件後,就來研究語法吧!
EventTarget.addEventListener(event, eventHandler, boolean)
內建的監聽事件很多,像是滑鼠的點擊、移動、聚焦,各種使用者在瀏覽器上可以進行的行為都有對應的事件,詳細可以到 MDN 列出的表格查看。
與舊式事件綁定寫法不同,事件名稱不需要加上 on
ex. 點擊事件寫在 html 是 onclick
,但在事件監聽器是 click
。
事件觸發後要執行的程式,可以是匿名或具名函式。
第三個參數為 boolean 值,決定監聽事件是要綁定在捕獲階段還是冒泡階段上。
false
: 預設值,表示將監聽事件綁定在 冒泡階段 Bubbling Phase 上true
:表示將監聽事件綁定在 捕獲階段 Capturing Phase上詳細的解釋推薦看這篇 事件迴力鏢 - 捕獲與冒泡,接下來讓我用變色圈圈告訴你差別~
設置三個分別為大中小的圈圈,每個圈圈綁定點擊時會亮起各自的背景色,大概的 html 階層如下。
變色上為了讓傳遞的效果明顯一點,加上 setTimeout
設定時間差異,但以下解釋先省略這部分,主要介紹綁定在冒泡階段與綁定在捕獲階段的差異。
// 圈圈層層包裹
<div class='big'>
<div class='middle'>
<div class='small'></div>
</div>
</div>
將點擊事件綁定在冒泡階段
// 綁定事件的第三個參數都設為 false
bigCircle.addEventListener("click", changeBlue, false); // 點擊大圈圈背景變深藍
middleCircle.addEventListener("click", changePurple, false); // 點擊中圈圈背景變紫色
smallCircle.addEventListener("click", changeLightblue, false); // 點擊小圈圈背景變淺藍
動作:點擊小圈圈
結果:小圈圈先亮 -> 中圈圈亮 -> 大圈圈亮
可以看到冒泡階段的傳遞方向,是由內層的標籤一路往外傳,當小圈圈收到點擊時,會再往外傳到中圈圈,中圈圈再往外傳到大圈圈,一直到最外層的 window 為止。
將點擊事件綁定在捕獲階段
// 綁定事件的第三個參數都設為 false
bigCircle.addEventListener("click", changeBlue, true); // 點擊大圈圈背景變深藍
middleCircle.addEventListener("click", changePurple, true); // 點擊中圈圈背景變紫色
smallCircle.addEventListener("click", changeLightblue, true); // 點擊小圈圈背景變淺藍
動作:點擊最小圈圈
結果:大圈圈先亮 -> 中圈圈亮 -> 小圈圈亮
順序跟剛剛不同!因為捕獲階段的順序是從最外層的標籤傳到最內層,所以大圈圈會先經歷捕獲階段,因此先捕捉到點擊事件亮起背景色,而小圈圈是整個捕獲階段的終點,最後才收到點擊事件。
所以囉,可以透過傳遞的方向差異製造不同的效果,一開始的燈泡就是將點擊事件階段綁定在 捕獲階段 capturing phase,所以當點擊燈泡時,黑色燈光是從外暗到內!
每次學到新的語法就迫不及待試試可以做出什麼效果,覺得開心 ≧ω≦