[分享] A15, 如何往事件監聽器裡傳參數 & 何謂監聽器事件「event」

Lastor
Code 隨筆放置場
4 min readAug 12, 2019

--

寫作業碰到問題,
用的關鍵字方向不對, 查好久查不到解,
正想說放棄掙扎來問助教時, 腦中閃過另一個關鍵字時, 終於給我查到了!!

在這邊分享一下。
一組加入事件監聽器的code如下:

HTMLElement.addEventListener('click', function () {
console.log(event.target)
})

如果有兩三組以上相同的監聽事件, 想要加在不同的元件上時,
因為裡面匿名function的內容是幾乎一樣的, 自然會想把function單獨拉出來傳入參數。

function foo(param1) {
if ( event.target.matches('css選擇器') ) { // 報錯, typeError!!
console.log(param1)
}
}
HTMLElement.addEventListener('click', foo(param1))

但是一改成上面那樣, event.target那邊就會報錯

TypeError: Cannot read property 'target' of undefined

我最開始以為問題是出在 .target 上面。
但看一看發現, 是出在event上頭。
如果用console.log檢測, 可以發現event是空的

function foo(param1) {
console.log(event) // undefined
if ( event.target.matches('css選擇器') ) { // 報錯, typeError!!
console.log(param1)
}
}
HTMLElement.addEventListener('click', foo(param1))

這個很尷尬, 稍微研究之後發現,
VScode之類的編輯器, 會把event變色, 看到它顏色不一樣,
我們當然會把event理解成是一個指令之類的。
但如果直接在VScode的debugger call它,
它會出現錯誤, 未定義變數。

如果在Chrome的console裡面call, 則會出現 undefined。

也就是說, event 這個東西, 它應該是一個DOM API。
預設是一個尚未給值的空變數。

那為什麼在寫入事件監聽器時, event.target可以工作呢?
這就要來說說 addEventListener() 到底是怎麼工作的。

根據MDN上, 關於 addEventListener() 的工作方式說明,
它會將輸入的event作為參數, 傳至後方的函式中。
所以是類似這樣的概念

addEventListener('event', function (event) { code })

第一個參數給上了一個「事件」之後,
它會把這個「事件」存放到上面提到的空變數event裡面,
然後傳給第二個參數, 讓裡面的function調用event。
因此在後面的function上頭, 使用event.target是可以工作的。

也因為這樣, 才會規定要使用命名函式的話, 不能加上( ), 不然JS會錯亂。

function foo() {
console.log('hi')
}
HTMLElement.addEventListener('click', foo) // foo不能加()

那如果我用於事件監聽器的function, 想要傳入自定義參數時, 可以怎麼做??
其實只要稍微逆轉一下思考就行了……

function foo(param) {
console.log('param')
}
// NG
HTMLElement.addEventListener('click', foo(param))
// OK
HTMLElement.addEventListener('click', function() {
foo(param)
}
)

參考,
Event — Web APIs | MDN
EventTarget.addEventListener() — Web APIs | MDN
晕了 addEventListener怎么往里面传参??-CSDN论坛

--

--

Lastor
Code 隨筆放置場

Web Frontend / 3D Modeling / Game and Animation. 設計本科生,前遊戲業 3D Artist,專擅日本動畫與遊戲相關領域。現在轉職為前端工程師,以專業遊戲美術的角度涉足 Web 前端開發。