EP.4 RE:從零開始的學習 JS 生活-第四日之事件與事件監聽

前言

轉生第四日,前一天了解了選取器後,接下來就必須來了解事件以及事件監聽。

事件 Event

事件有很多種,所以這邊僅列常見的事件,而事件其實就是在講你的動作,例如你按下按鈕的動作、滑鼠拖曳的動作甚至拖曳視窗的動作,這些都統稱事件,又可以稱之為事件處理器(event handlers),最主要是監聽使用者的任何一個操作動作,但是監聽又是另一回事。

一般常見的事件會有 clickchangeblur 等,而這些都是屬於 JavaScript 的 Event 事件,早期的網站開發你可能會看到這種事件 onclickonchange 甚至是 onmouseover 等等,這些有 on 開頭的,居多都是都是直接寫在 HTML 上,如:

1
<button onclick="alert('Ray')">你叫什麼?</button>

以現階段開發來講比較少人使用這種方式,最主要這種寫法會導致維護上的困擾,光是修改一個事件你可能就會找老半天,所以現在大多開發者都會將事件寫在一隻 JavaScript 中,當然你還是有機會可以看到這種寫法。

codepen:https://codepen.io/hsiangfeng/pen/NWKyPRE

See the Pen HTML onclick by HF (@hsiangfeng) on CodePen.

事件監聽

事件監聽簡單來講起來就是我「請一個人盯著你特定的行為動作」,例如我盯著你何時會按下按鈕的這個動作或是你滑鼠移動的軌跡,前面有講到現在開發都會將事件監聽寫在 JavaScript 檔案中,那麼該如何撰寫事件監聽呢?使用事件監聽的語法是 addEventListener() 它可以將你指定的特定事件註冊至你帶入的事件中,這樣講其實滿模糊的,來看一下範例:

假如使用者點擊按鈕時會觸發事件並顯示跟我打招呼,那 JavaScript 就可以像以下範例這樣寫,但是我們必須先使用選取器選取你要監聽哪一個 DOM 元素,否則怎麼知道你要監聽哪一個呢?

1
2
3
4
5
6
7
// 選取欲監聽的元素
var clickId = document.getElementById('clickme');

// 第一個參數是要監聽的事件 第二個參數是觸發事件後要執行的動作 第三個後面在介紹
clickId.addEventListener('click', function() {
console.log('My Name is Ray');
}) // 注意 JavaScript 的事件可以不用加上 on

那當你點擊按鈕後就會出現 My Name is Ray

事件觸發

所以 addEventListener() 的參數說明就像這樣 ↓

addEventListener 說明

codepen:https://codepen.io/hsiangfeng/pen/rNBJaWa

See the Pen 事件監聽 by HF (@hsiangfeng) on CodePen.

事件流程

第三個參數是所謂的 事件流程 它只能夠接受 Boolean,也就是 true or false,並且可以選擇是否填入或是留空,通常預設留空是 false,那事件流程是什麼呢?讓我們從範例來看。

HTML 部分 :

1
2
3
4
5
6
<div class="box1" id="box1">
box1
<div class="box2" id="box2">
box2
</div>
</div>

CSS 部分:

1
2
3
4
5
6
7
8
9
10
11
.box1 {
border: 1px solid red;
background: red;
height: 200px;
}
.box2 {
border: 1px solid blue;
background: blue;
color: white;
height: 100px;
}

JavaScript:

1
2
3
4
5
6
7
8
9
10
11
var box1 = document.getElementById('box1');
box1.addEventListener('click', function(e) {
alert('box1');
console.log('box1');
},true);

var box2 = document.getElementById('box2');
box2.addEventListener('click', function(e) {
alert('box2');
console.log('box2');
},true);

所以目前顯示畫面是這樣 ↓

目前顯示

正常來講當我們點擊任何一個 box1 ~ 2 都應該只會出現我們點擊的 box,但是如果我們將第三個參數改為 true 並點擊 box2 將會發生什麼事情呢?

box1 → box2

可以發現明明點擊的是 box2 但是 box1 卻也跳出來,那如果將第三個參數改為預設 false 在點一次 box2 呢?

box2 → box1

可以發現結果反過來輸出,而且還會穿透過去,所以說第三個參數的 false & true 分別代表著以下意思:

  • false - 從指定元素往外層觸發
  • true - 由外層往指定元素觸發

若是以圖片來範例的話就會像這樣,首先是預設的 false 狀況 ↓

從指定元素往外層觸發

那麼 true 則是反過來 ↓

由外層往指定元素觸發

當然第三個參數是有比較正式的說法

  • false - 事件氣泡(Event Bubbling)
  • true - 事件捕捉(Event capturing)

事件氣泡的意思,以異世界來舉例,你可以想像成你在大草原上面看著一個兔子(指定元素),然後再往其他草原(外層)的部分尋找別的兔子。

那麼事件捕捉的話,則是你從大草原(外層)裡面尋找一隻兔子(指定元素)。

但是有時候我們會不希望發生事件氣泡 or 事件捕捉的狀況,那麼 JavaScript 就有提供一個語法幫助我們解決這個問題,也就是 stopPropagation();,也就是阻止當前事件繼續進行捕捉(capturing)及冒泡(bubbling)階段的傳遞,當你加入後不管怎麼點 box2 就不會跳出 box1

stopPropagation

codepen:https://codepen.io/hsiangfeng/pen/xxKYxro/

See the Pen 禁止事件氣泡 by HF (@hsiangfeng) on CodePen.

結尾

下一篇的 RE:從零開始的學習 JS 生活-第五日 將會介紹陣列與物件。