๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ Deep Dive ๋์์ 40์ฅ ์ด๋ฒคํธ๋ฅผ ์ ๋ฆฌํ์์ต๋๋ค.
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ํธ์ถ๋ ํจ์๋ฅผ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ผ ํ๊ณ , ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ๋ธ๋ผ์ฐ์ ์๊ฒ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ํธ์ถ์ ์์ํ๋ ๊ฒ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ๋ก์ด๋ผ ํ๋ค.
์ด๋ฒคํธ์ ๊ทธ์ ๋์ํ๋ ํจ์๋ฅผ ํตํด ์ฌ์ฉ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํธ์์ฉ์ ํ ์ ์๋ค. ์ด์ ๊ฐ์ด ํ๋ก๊ทธ๋จ์ ํ๋ฆ์ ์ด๋ฒคํธ ์ค์ฌ์ผ๋ก ์ ์ดํ๋ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ ์ด๋ฒคํธ ๋๋ฆฌ๋ธ ํ๋ก๊ทธ๋๋ฐ์ด๋ผํ๋ค.
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ๋ธ๋ผ์ฐ์ ์๊ฒ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ํธ์ถ์ ์์ํ๋ ๊ฒ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ๋ก์ด๋ผ ํ๋ค.
onclick๊ณผ ๊ฐ์ด on
์ ๋์ฌ์ ์ด๋ฒคํธ์ ์ข
๋ฅ๋ฅผ ๋ํ๋ด๋ ์ด๋ฒคํธ ํ์
์ผ๋ก ์ด๋ฃจ์ด์ ธ ์๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๊ฐ์ผ๋ก ํจ์ ํธ์ถ๋ฌธ ๋ฑ์ ๋ฌธ์ ํ ๋นํ๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋ฑ๋ก๋๋ค.
์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ๋ก์ด๋ ํจ์ ํธ์ถ์ ๋ธ๋ผ์ฐ์ ์๊ฒ ์์ํ๋ ๊ฒ์ด๋ผ ํ๋ค. ๋ฐ๋ผ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ๋กํ ๋ ์ฝ๋ฐฑ ํจ์์ ๋ง์ฐฌ๊ฐ์ง๋ก ํจ์ ์ฐธ์กฐ๋ฅผ ๋ฑ๋กํด์ผ ๋ธ๋ผ์ฐ์ ๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํธ์ถํ ์ ์๋ค.์ฆ, ํจ์๊ฐ ์๋ ๊ฐ์ ๋ฐํํ๋ ํจ์ ํธ์ถ๋ฌธ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ก ๋ฑ๋กํ๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํธ์ถํ ์ ์๋ค.
์๋ฅผ ๋ค์ด onclick="sayHi('Lee')"
์ดํธ๋ฆฌ๋ทฐํธ๋ ํ์ฑ๋์ด ์๋์ ๊ฐ์ ํจ์๋ฅผ ์๋ฌต์ ์ผ๋ก ์์ฑํ๊ณ , ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ์ด๋ฆ๊ณผ ๋์ผํ ํค onclick ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ํ ๋น๋๋ค.
function onclick(event){
sayHi('Lee')
}
์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ํค๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ์ ๋ง์ฐฌ๊ฐ์ง๋ก onclick๊ณผ ๊ฐ์ด on ์ ๋์ฌ์ ์ด๋ฒคํธ์ ์ข ๋ฅ๋ฅผ ๋ํ๋ด๋ ์ด๋ฒคํธ ํ์ ์ผ๋ก ์ด๋ฃจ์ด์ ธ ์๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ํจ์๋ฅผ ๋ฐ์ธ๋ฉํ๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋ฑ๋ก๋๋ค.
์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๊ธฐ ์ํด์๋ ์ด๋ฒคํธ ํ๊น๊ณผ ์ด๋ฒคํธ ํ์ , ๊ทธ๋ฆฌ๊ณ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ง์ ํ ํ์๊ฐ ์๋ค.
// $button: ์ด๋ฒคํธ ํ๊น
// on + ์ด๋ฒคํธ ํ์
// function: ์ด๋ฒคํธ ํธ๋ค๋ฌ
$button.onclick = function () {
console.log('button click')
}
์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ํ๋์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ง ๋ฐ์ธ๋ฉํ ์ ์๋ค๋ ๋จ์ ์ด ์๋ค.
EventTarget.addEventListener('eventType', functionName, [, useCapture])
// ์ด๋ฒคํธ ํ๊น.addEventListener(์ด๋ฒคํธ ํ์
, ์ด๋ฒคํธ ํธ๋ค๋ฌ, capture ์ฌ์ฉ ์ฌ๋ถ)
addEventListener
๋ฉ์๋์๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ธ์๋ก ์ ๋ฌํ๋ค. ๋ํ ํ๋ ์ด์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ์ ์๋ค. ์ด๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ๋ฑ๋ก๋ ์์๋๋ก ํธ์ถ๋๋ค.
๋จ, ์ฐธ์กฐ๊ฐ ๋์ผํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ค๋ณต ๋ฑ๋กํ๋ฉด ํ๋์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ง ๋ฑ๋ก๋๋ค.
addEventListener ๋ฉ์๋๋ก ๋ฑ๋กํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ ๊ฑฐํ๋ ค๋ฉด EventTarget.prototype.removeEventListener ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค. ์ฌ๊ธฐ์ ์ ๋ฌํ ์ธ์๋ addEventListener ๋ฉ์๋์ ๋์ผํ๋ค.
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์ด๋ฒคํธ์ ๊ด๋ จ๋ ๋ค์ํ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ๋์ ์ผ๋ก ์์ฑ๋๋ค. ์์ฑ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ฒซ ๋ฒ์งธ ์ธ์(๋งค๊ฐ๋ณ์ e)๋ก ์ ๋ฌ๋๋ค. ์ด๋ ๋ธ๋ผ์ฐ์ ๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํธ์ถ ํ ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์ธ์๋ก ์ ๋ฌํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์๋ฌต์ ์ผ๋ก ์์ฑ๋๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์์ฑ์ ํจ์์ ์ํด ์์ฑ๋๋ค. ์์ฑ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์์ฑ์ ํจ์์ ๋๋ถ์ด ์์ฑ๋๋ ํ๋กํ ํ์ ์ผ๋ก ๊ตฌ์ฑ๋ ํ๋กํ ํ์ ์ฒด์ธ์ ์ผ์์ด ๋๋ค.
Event ์ธํฐํ์ด์ค ์ฆ, Event.prototype์ ์ ์๋์ด ์๋ ์ด๋ฒคํธ๊ด๋ จ ํ๋กํผํฐ๋ UIEvent, CustomEvent, MouseEvent ๋ฑ ๋ชจ๋ ํ์ ์ด๋ฒคํธ ๊ฐ์ฒด์ ์์๋๋ค. Event ์ธํฐํ์ด์ค์ ์ด๋ฒคํธ ๊ด๋ จ ํ๋กํผํฐ๋ ๋ชจ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์๋ฐ๋ ๊ณตํต ํ๋กํผํฐ๋ค.
DOM ํธ๋ฆฌ ์์ ์กด์ฌํ๋ DOM ์์ ๋ ธ๋์์ ๋ฐ์ํ ์ด๋ฒคํธ๋ DOM ํธ๋ฆฌ๋ฅผ ํตํด ์ ํ๋๋ค. ์ด๋ฅผ ์ด๋ฒคํธ ์ ํ๋ผ๊ณ ํ๋ค.
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๊ณ ์์ฑ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์ด๋ฒคํธ๊ฐ ๋ฐ์์ํจ DOM ์์์ธ ์ด๋ฒคํธ ํ๊น์ ์ค์ฌ์ผ๋ก DOM ํธ๋ฆฌ๋ฅผ ํตํด ์ ํ๋๋ค.
์ฌ๋ฌ ๊ฐ์ ํ์ DOM ์์์ ๊ฐ๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ ๋์ ํ๋์ ์์ DOM ์์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ์ ๋งํ๋ค.
preventDefault
๋ฉ์๋๋ DOM์์์ ๊ธฐ๋ณธ ๋์์ ์ค๋จ์ํจ๋ค.
stopPropagation
๋ฉ์๋๋ ์ด๋ฒคํธ ์ ํ๋ฅผ ์ค์ง์ํจ๋ค.
handleClick ํจ์๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ํด ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋๊ธฐ ๋๋ฌธ์ ์ ์ญ๊ฐ์ฒด window๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
<button onclick="handleClick()">Click me</button>
<script>
function handleClick() {
console.log(this) // window
}
</script>
์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
<button onclick="handleClick(this)">Click me</button>
<script>
function handleClick(button) {
console.log(button) // ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ button ์์
}
</script>
์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๋ฅผ ๊ฐ๋ฆฌํจ๋ค. ์ฆ, ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ ์ด๋ฒคํธ ๊ฐ์ฒด์ currentTarget ํ๋กํผํฐ์ ๊ฐ๋ค.
ํ์ดํ ํจ์๋ก ์ ์ํ ์ด๋ฒคํธ ๋ด๋ถ์ this๋ ์์ ์ค์ฝํ์ this๋ฅผ ๊ฐ๋ฆฌํจ๋ค. ํ์ดํ ํจ์๋ ํจ์ ์์ฒด์ this ๋ฐ์ธ๋ฉ์ ๊ฐ์ง ์๋๋ค.
<button class="btn1">0</button>
<script>
const $button1 = document.querySelector('.btn1')
$button1.addEventListener('click', e => {
console.log(this) // window
console.log(e.currenetTarget) // $button1
})
// window.textContent์ NaN(undefined + 1)์ ํ ๋นํ๋ค.
++this.textContent
</script>
๊ฐ๋ฐ์์ ์๋๋ก ์์ฑ๋ ์ด๋ฒคํธ๋ฅผ ์ปค์คํ ์ด๋ฒคํธ๋ผ ํ๋ค.
์ด๋ฒคํธ ์์ฑ์ ํจ์๋ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ด๋ฒคํธ ํ์ ์ ๋ํ๋ด๋ ๋ฌธ์์ด์ ์ ๋ฌ๋ฐ๋๋ค.
// KeyBoardEvent ์์ฑ์ ํจ์๋ก keyup ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const ketboardEvent = new KeyboardEvent('keyup')
console.log(ketboardEvent.type) // keyup
// CustomEvent ์์ฑ์ ํจ์๋ก foo ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const customEvent = new CustomEvent('foo')
console.log(customEvent.type) // foo
์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ bubbles์ cancelable ํ๋กํผํฐ์ ๊ฐ์ด false
๋ก ๊ธฐ๋ณธ ์ค์ ๋์ด์์ด์ ๋ฒ๋ธ๋ง๋์ง ์๊ณ preventDefault ๋ฉ์๋๋ก ์ทจ์ํ ์๋ ์๋ค.
๋ง์ฝ์ ์ด ๋ถ๋ถ์ true๋ก ์ค์ ํ๋ ค๋ฉด ๋๋ฒ์งธ ์ธ์๋ก bubbles ๋๋ cancelable ํ๋กํผํฐ๋ฅผ ๊ฐ๋ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋ค.
์์ฑ๋ ์ปค์คํ
์ด๋ฒคํธ๋ dispatchEvent
๋ฉ์๋๋ก ๋์คํจ์น(์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํค๋ ํ์) ํ ์ ์๋ค. dispatchEvent
๋ฉ์๋์ ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์ธ์๋ก ์ ๋ฌํ๋ฉด์ ํธ์ถํ๋ฉด ์ ๋ฌํ ์ด๋ฒคํธ ํ์
์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ค.
// ์ปค์คํ
์ด๋ฒคํธ ๋์คํจ์น(๋๊ธฐ ์ฒ๋ฆฌ). click ์ด๋ฒคํธ ๋ฐ์
$button.dispatchEvent(customEvent)
์ผ๋ฐ์ ์ผ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ฐฉ์์ผ๋ก ๋์ํ์ง๋ง dispatchEvent ๋ฉ์๋๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋๊ธฐ์ฒ๋ฆฌ ๋ฐฉ์์ผ๋ก ํธ์ถํ๋ค. ๋ฐ๋ผ์ ์ด๋ฒคํธ๋ฅผ ๋์คํจ์น ํ๊ธฐ ์ด์ ์ ์ปค์คํ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํด์ผํ๋ค.
๊ธฐ์กด ์ด๋ฒคํธ ํ์
์ด ์๋๋ผ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๊ฒฝ์ฐ ๋ฐ๋์ addEventListener
๋ฉ์๋ ๋ฐฉ์์ผ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํด์ผ ํ๋ค.
Ref
- ์ด์ ๋ชจ ์ , โ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ Deep Diveโ, ์ํค๋ถ์ค