前言
有利用傳統三元素(HTML/CSS/JS)打造專案的朋友應該對於addEventListener的語法都不陌生,前幾天學生問了一個相當有趣的問題,雖然有些超出他們目前所接觸的範圍,但我認為相當有意思,於是在此做個紀錄。
addEventListener基礎事件監聽
我們都很清楚如果我今天想利用JS操作DOM元素,事件監聽與處理是必不可少的過程,舉個例子來說,我希望點擊了某個按鈕後電腦就很貼心的問我今天過得如何,整段code大概就會像這個樣子。
demo code
<button id="btn">Click Me</button>
<script>
const btn = document.getElementById('btn')
btn.addEventListener('click',greeting)
function greeting() {
alert(`Hello, Danny`)
}
</script>
看起來沒有什麼問題,實際上也的確沒有什麼問題! 不過今天如果不同的使用者點擊,需要傳遞不同的name作為參數又如何呢?我們彼此都很清楚不能直接寫為
btn.addEventListener('click',greeting('Danny'))
那究竟該怎麼辦? 其實方法相當的簡單,我這邊提供兩種做法!
方法一:利用閉包
原理相當的單純,我們只要在原先的function部分改為回傳一個匿名函數,此匿名函數便可以作為callback乖乖等待event呼叫後再handle,也就是將原先的function改為以下
function greeting(name) {
return function(){
alert(`Hello, ${name}`)
}
}
藉由這樣function return function我們創造了一個閉包(closure),隱藏了name這個參數但同時又讓匿名函數有辦法使用name的值! 有興趣的話可以試試看以下的codepen demo。
方法二:利用bind
這個就是更加常見的做法了,我們知道bind在綁定物件的同時也可以傳進參數,理解到這一點後我們只要將handler的內容作一點修改即可!
btn.addEventListener('click',greeting.bind(null,'Danny'))
function greeting(name) {
alert(`Hello, ${name}`)
}
結語
回來當助教後,再一次發現有時學生問的問題真的很~有意思,他們不見得理解自己戳到什麼大坑,不過像這樣的原理探究我一值都是很喜歡的。希望藉由這篇文章能幫助有同樣困擾的程式學習者~一起繼續加油唄!