iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 3
0
Modern Web

JavaScript 忍者的修練--從下忍進階到中忍系列 第 3

Day 03: 網頁生命週期之事件處理

事件類型

Web app 是圖像化的操作介面,使用者透過 UI 介面執行任務,產生各種事件(event)。在頁面建置階段的 JavaScript 程式碼,還需要註冊事件處置器(event-handler),也就是告訴瀏覽器在這些事件發生時,要執行的函式。

在 web app 裡主要有這幾種事件類型:

使用者事件:點擊、鍵盤輸入、移動滑鼠
瀏覽器事件:網頁處於已載入或未載入的狀態
網路事件:來自伺服器的回應
計時器事件:setTimeoutsetInterval

Event loop

瀏覽器的執行環境是單一執行緒模型(single-threaded execution model),也就是說 JavaScript 引擎一次只能處理一段程式碼。

想像一下你到福利熊超市買東西,結帳櫃台一次只能服務一位客人,當太多客人在排隊客人就會生氣,這個時候櫃台就會廣播「請支援收銀」,多開幾個櫃台分散排隊的人潮,加快結帳的速度。

不過這間 JavaScript 超市櫃台竟然只有一個(單執行緒)!所以每個客人(事件)都必須排在同一個隊伍裡,萬一前面的客人一次買了整個購物推車的東西,後面的客人就要等久一點,你一定有過這樣的經驗吧。

在瀏覽器的環境裡事件會一直發生,就像是超市一直會有人進來買東西,於是 JavaScript 也有一套管理事件的機制,事件依發生的順序被安排在一個隊列(event queue)裡,如果目前沒有程式碼在跑,位在 event queue 第一個的事件裡的程式碼會被提取出來執行,一直到 event queue 清空,這個機制叫做 event loop,因為它是個一直在檢查 event queue 的迴圈。這就很像我們進銀行要先抽號碼牌,叫到我們的號碼才到櫃台,在這之前只能等待。

註冊 event-handlers

我們可以事先寫一段函式在事件發生時讓瀏覽器執行,這是透過註冊 event-handlers,當符合條件的事件發生時,其函式就會被放進 event queue 當中。

Event-handlers 有二種,第一種是瀏覽器內建的 global event-handler,常見的有onload, onclick等等。

要注意內建的 event-handler 只能加載一個函式,如果註冊了新的函式,新函式會取代原有的函式。

var button = document.getElementById("button");
button.onclick = function(){
	console.log("福利熊");
};
button.onclick = function(){
	console.log("熊福利");
};

// 點擊 button 後只會印出 "熊福利"

如上範例我們取得頁面的 #button元素,先在按鈕用內建的onclick註冊會印出「福利熊」的函式,再註冊一個會印出「熊福利」的新函式。點擊按鈕卻只會得到「熊福利」的結果☹️,也就是說新函式覆蓋了之前註冊的事件函式。這在和別人共同開發專案時會帶來困擾,因為你的新函式會不小心覆蓋了同事的函式,讓原有的功能突然不能使用,麻煩的是這不會有錯誤訊息。

好在我們還有另外一個內建的 addEventListener 方法,可以在一個元素上註冊多個事件函式。

var button = document.getElementById("button");
button.addEventListener("click", function(){
	console.log("福利熊");
});
button.addEventListener("click", function(){
	console.log("熊福利");
});
// 點擊 button 後印出 "福利熊 熊福利"

在同一個按鈕上先後使用addEventListener註冊二個函式在click事件上,這一次點擊按鈕得到「福利熊 熊福利」的結果。


上一篇
Day 02: 網頁生命週期之頁面建置
下一篇
Day 04: 函式是頭等物件
系列文
JavaScript 忍者的修練--從下忍進階到中忍30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言