๋ธ๋ผ์ฐ์ ๋ ์ฒ๋ฆฌํด์ผ ํ ํน์ ์ฌ๊ฑด์ด ๋ฐ์ํ๋ฉด ์ด๋ฅผ ๊ฐ์งํ์ฌ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ๋ค. ๋ง์ฝ ์ด ๋ ์ด๋ฒคํธ์ ๋ํด ๋ฐ์ํ์ฌ ์ด๋ค ์ผ์ ํ๊ณ ์ถ๋ค๋ฉด ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ํธ์ถ๋ ํจ์๋ฅผ ๋ธ๋ผ์ฐ์ ์๊ฒ ์๋ ค ํธ์ถ์ ์์ํ๋ค. ์ฐ๋ฆฌ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํตํด ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ์ํ๋ ๋์์ ํ ์ ์๋ค.
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ํธ์ถ๋ ํจ์๋ฅผ ์ด๋ฒคํธ ํธ๋ค๋ฌ(event handler)๋ผ ํ๋ค. ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ๋ธ๋ผ์ฐ์ ์๊ฒ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ํธ์ถ์ ์์ํ๋ ๊ฒ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ๋ก์ด๋ผ ํ๋ค.์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ์ 3๊ฐ์ง๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ก๋ ํจ์ ์ฐธ์กฐ๊ฐ ๋ฑ๋ก๋์ด์ผํ๋ค.
์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๊ฐ์ผ๋ก ํจ์ ํธ์ถ๋ฌธ ๋ฑ์ ๋ฌธ์ ํ ๋นํ๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋ฑ๋ก๋๋ค. ์ด๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๊ฐ์ผ๋ก ๋ฑ๋ก๋ ํจ์ ํธ์ถ๋ฌธ์ ์ฌ์ค ์๋ฌต์ ์ผ๋ก ์์ฑ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ํจ์ ๋ชธ์ฒด๋ฅผ ์๋ฏธํ๋ค. ๊ทธ๋ฌ๋ ์ด ๋ฐฉ์์ HTML๊ณผ ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ํผ์ฌํจ์ผ๋ก ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ์ข๋ค.
<button onClick='sayHi('Lee')'>click me!</button>
DOM ๋ ธ๋ ๊ฐ์ฒด๋ ์ด๋ฒคํธ์ ๋์ํ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ํจ์๋ฅผ ๋ฐ์ธ๋ฉํ๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋ฑ๋ก๋๋ค. ์์ ์ดํด๋ณธ ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๋ฐฉ์๋ ๊ฒฐ๊ตญ ๋ ธ๋ ๊ฐ์ฒด์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ๋ก ๋ณํ๋๋ฏ๋ก ๊ฒฐ๊ณผ์ ์ผ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์๊ณผ ๋์ผํ๋ค๊ณ ํ ์ ์๋ค. ํ๋์ ํ๋กํผํฐ์ ํ๋์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ง ๋ฐ์ธ๋ฉํ ์ ์๋ค๋ ๋จ์ ์ด ์๋ค.
// $button = ์ด๋ฒคํธ ํ๊น
// onclick = on + ์ด๋ฒคํธ ํ์
// function = ์ด๋ฒคํธ ํธ๋ค๋ฌ
$button.onclick = function () {
console.log('button click');
};
DOM Level 2์์ ๋์ ๋ EventTarget.prototype.addEventListener ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ์ ์๋ค. ์์ ์ดํด๋ณธ ๋ ๋ฐฉ์์ DOM Level 0๋ถํฐ ์ ๊ณต๋๋ ๋ฐฉ์์ด๋ค. ์์ ํ๋กํผํฐ ๋ฐฉ์๊ณผ ๋ฌ๋ฆฌ addEventListener ๋ฉ์๋์๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ธ์๋ก ์ ๋ฌํ๋ค.
addEventListener ๋ฉ์๋ ๋ฐฉ์์ ๋์ผํ HTML ์์์์ ๋ฐ์ํ ๋์ผํ ์ด๋ฒคํธ์ ๋ํด ํ๋ ์ด์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ์ ์๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ๋ฑ๋ก๋ ์์๋๋ก ํธ์ถ๋๋ค.
$button.addEventListener('click', function () {
console.log('button click');
});
addEventListener ๋ฉ์๋๋ก ๋ฑ๋กํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ ๊ฑฐํ๋ ค๋ฉด EventTarget.prototype.removeEventListener ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค. removeEventListener ๋ฉ์๋์ ์ ๋ฌํ ์ธ์๋ addEventListener ๋ฉ์๋์ ๋์ผํด์ผ๋ง ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์ ๊ฑฐ๋๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์์ผ๋ก ๋ฑ๋กํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ ๊ฑฐํ๋ ค๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ null์ ํ ๋นํ๋ค.
$button.addEventListener('click', function foo() {
console.log('button click');
});
// ์ฑ๊ณต์ ์ผ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ foo๊ฐ ์ ๊ฑฐ๋๋ค.
$button.removeEventListener('click', foo);
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์ด๋ฒคํธ์ ๊ด๋ จํ ๋ค์ํ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ๋์ ์ผ๋ก ์์ฑ๋๋ค. ์์ฑ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌ๋๋ค. ํด๋ฆญ ์ด๋ฒคํธ์ ์ํด ์์ฑ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌ๋์ด ๋งค๊ฐ๋ณ์ e์ ์๋ฌต์ ์ผ๋ก ํ ๋น๋๋ค.
์ด๋ ๋ธ๋ผ์ฐ์ ๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํธ์ถํ ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํธ์ถํ ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์ธ์๋ก ์ ๋ฌํ๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฐ๋ผ์ ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์ ๋ฌ๋ฐ์ผ๋ ค๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ ์ํ ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์ ๋ฌ๋ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ๋ช
์์ ์ผ๋ก ์ ์ธํด์ผ ํ๋ค.
$button.addEventListener('click', foo());
const foo = function (e) {
console.log(e.target);
}
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์ด๋ฒคํธ ํ์ ์ ๋ฐ๋ผ ๋ค์ํ ํ์ ์ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค. ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ ์์ ๊ตฌ์กฐ๋ฅผ ๊ฐ๋๋ค. ์ ๊ทธ๋ฆผ์ Event, UIEvent, MouseEvent ๋ฑ ๋ชจ๋๋ ์์ฑ์ ํจ์๋ค.
const e = new MouseEvent('click');
console.log(e);
// MouseEvent {isTrusted: false, screenX: 0, screenY: 0, clientX: 0, ...}
// MouseEvent ์์ฑ์ ํจ์๋ฅผ ํธ์ถํ์ฌ click ์ด๋ฒคํธ ํ์
์ MouseEvent ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
์ ์์ ์ฝ๋์ ๊ฐ์ด ์์ฑ์ ํจ์๋ฅผ ํธ์ถํ์ฌ ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์๋ค. ์ด์ฒ๋ผ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์๋ฌต์ ์ผ๋ก ์์ฑ๋๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์์ฑ์ ํจ์์ ์ํด ์์ฑ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์์ฑ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์์ฑ์ ํจ์์ ๋๋ถ์ด ์์ฑ๋๋ ํ๋กํ ํ์ ์ผ๋ก ๊ตฌ์ฑ๋ ํ๋กํ ํ์ ์ฒด์ธ์ ์ผ์์ด ๋๋ค.
์๋ฅผ ๋ค์ด, click ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์๋ฌต์ ์ผ๋ก ์์ฑ๋๋ MouseEvent ํ์ ์ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ๋ค์๊ณผ ๊ฐ์ ํ๋กํ ํ์ ์ฒด์ธ์ ์ผ์์ด ๋๋ค.
Event ์ธํฐํ์ด์ค, ์ฆ Event.prototype์ ์ ์๋์ด ์๋ ์ด๋ฒคํธ ๊ด๋ จ ํ๋กํผํฐ๋ ๋ชจ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์๋ฐ๋ ๊ณตํต ํ๋กํผํฐ๋ค. ์ด๋ค ๊ฒ๋ค์ด ์๋์ง ์ดํด๋ณด์. MouseEvent๋ KeyboradEvent ๋ฑ ๋ค๋ฅธ ์ด๋ฒคํธ๋ค์ ๊ฐ๊ฐ ์ด๋ฒคํธ์ ๋ง๋ ๋ค๋ฅธ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋ค. ๊ถ๊ธํ๋ค๋ฉด ์ง์ ์์๋ณด์.
๊ณตํต ํ๋กํผํฐ | ์ค๋ช | ํ์ |
---|---|---|
type | ์ด๋ฒคํธ ํ์ | string |
target | ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ DOM ์์ | DOM ์์ ๋ ธ๋ |
currentTarget | ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋ฐ์ธ๋ฉ๋ DOM ์์ | DOM ์์ ๋ ธ๋ |
eventPhase | ์ด๋ฒคํธ ์ ํ ๋จ๊ณ | number |
bubbles | ์ด๋ฒคํธ๋ฅผ ๋ฒ๋ธ๋ง์ผ๋ก ์ ํํ๋์ง ์ฌ๋ถ | boolean |
cancelable | preventDefault ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ด๋ฒคํธ์ ๊ธฐ๋ณธ ๋์์ผ๋ก ์ทจ์ํ ์ ์์ง ์ฌ๋ถ | boolean |
defaultPrevented | preventDefault ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ด๋ฒคํธ๋ฅผ ์ทจ์ํ๋์ง ์ฌ๋ถ | boolean |
isTrusted | ์ฌ์ฉ์์ ํ์์ ์ํด ๋ฐ์ํ ์ด๋ฒคํธ์ธ์ง ์ฌ๋ถ | boolean |
timeStamp | ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์๊ฐ(1970/01/01/00:00:0๋ถํฐ ๊ฒฝ๊ณผ ๋ฐ๋ฆฌ์ด) | number |
์ด๋ฒคํธ๊ฐ ๋ฐ์ํด ์์ฑ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ DOM ์์์ธ ์ด๋ฒคํธ ํ๊ฒ์ ์ค์ฌ์ผ๋ก DOM ํธ๋ฆฌ๋ฅผ ํตํด ์ ํ๋๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ์ด๋ฒคํธ ํ๊น ๋๋ ์ ํ๋ ์ด๋ฒคํธ๋ฅผ ์บ์นํ DOM ๋ ธ๋ ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉํ๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ/ํ๋กํผํฐ ๋ฐฉ์์ผ๋ก ๋ฑ๋กํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ํ๊น ๋จ๊ณ์ ๋ฒ๋ธ๋ง ๋จ๊ณ์ ์ด๋ฒคํธ๋ง ์บ์นํ ์ ์๋ค. ๊ทธ๋ฌ๋ addEventListener ๋ฐฉ์์ผ๋ก ๋ฑ๋กํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ๋ชจ๋ ๋จ๊ณ์ ์ด๋ฒคํธ๋ฅผ ์บ์นํ ์ ์๋ค.
์บก์ฒ๋ง ๋จ๊ณ(capturing phase): ์ด๋ฒคํธ๊ฐ ์์ ์์์์ ํ์ ์์ ๋ฐฉํฅ์ผ๋ก ์ ํ
(window โ target ๋ฐฉํฅ์ผ๋ก ์ ํ๋๋ค.)
ํ๊น ๋จ๊ณ(target phase): ์ด๋ฒคํธ๊ฐ ์ด๋ฒคํธ ํ๊น์ ๋๋ฌ
๋ฒ๋ธ๋ง ๋จ๊ณ(bubbling phase): ์ด๋ฒคํธ๊ฐ ํ์ ์์์์ ์์ ์์ ๋ฐฉํฅ์ผ๋ก ์ ํ
(target โ window ๋ฐฉํฅ์ผ๋ก ์ ํ๋๋ค.)
์์ ๋จ๊ณ ์์๋๋ก ์ด๋ฒคํธ๊ฐ ์ ํ๋๋ค. ์๋์์ addEventListener๋ฅผ ํตํด ์ด๋ฒคํธ๋ฅผ ์บ์นํ๋ ๊ฑธ ์์ธํ ์ดํด๋ณด์.
// index.html
<ul id="crews">
<li id="harry">Harry</li>
<li id="vordt">Vordt</li>
</ul>
// index.js
// $crew ์์์ ํ์ ์์์ธ li ์์๋ฅผ ํด๋ฆญํ ๊ฒฝ์ฐ ์บก์ฒ๋ง ๋จ๊ณ์ ์ด๋ฒคํธ๋ฅผ ์บ์นํ๋ค.
// ์บก์ฒ๋ง ๋จ๊ณ์ ์ด๋ฒคํธ๋ฅผ ์บ์นํ๋ ค๋ฉด 3๋ฒ์งธ ์ธ์๋ก true๋ฅผ ์ ๋ฌํด์ผํ๋ค.
$crews.addEventListener('click', e => {
console.log(`์ด๋ฒคํธ ๋จ๊ณ: ${e.eventPhase}`); // 1
console.log(`์ด๋ฒคํธ ํ๊น: ${e.target}`); // [object HTMLLIElement]
console.log(`ํ์ฌ ํ๊น: ${e.currentTarget}`); // [object HTMLUListElement]
}, true);
// ํ๊น ๋จ๊ณ์ ์ด๋ฒคํธ๋ฅผ ์บ์นํ๋ค.
$harry.addEventListener('click', e => {
console.log(`์ด๋ฒคํธ ๋จ๊ณ: ${e.eventPhase}`); // 2
console.log(`์ด๋ฒคํธ ํ๊น: ${e.target}`); // [object HTMLLIElement]
console.log(`ํ์ฌ ํ๊น: ${e.currentTarget}`); // [object HTMLLIElement]
});
// ๋ฒ๋ธ๋ง ๋จ๊ณ์ ์ด๋ฒคํธ๋ฅผ ์บ์นํ๋ค.
$crews.addEventListener('click', e => {
console.log(`์ด๋ฒคํธ ๋จ๊ณ: ${e.eventPhase}`); // 3
console.log(`์ด๋ฒคํธ ํ๊น: ${e.target}`); // [object HTMLLIElement]
console.log(`ํ์ฌ ํ๊น: ${e.currentTarget}`); // [object HTMLUListElement]
});
์ฐ๋ฆฌ๋ ์ด๋ฅผ ํตํด์ ์ด๋ฒคํธ๋ฅผ ์์ DOM์์์ ์์ํด์ ์ ์ฉํ๊ฒ ์จ๋จน์ ์ ์๋ค. ์ด๋ฒคํธ ์์(event delegation)์ ์ฌ๋ฌ ๊ฐ์ ํ์ DOM ์์์ ๊ฐ๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ ๋์ ํ๋์ ์์ DOM ์์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ์ ๋งํ๋ค. ์ด๋ฒคํธ ์์์ ํตํด ์์ DOM ์์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ฉด ์ฌ๋ฌ ๊ฐ์ ํ์ DOM ์์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ํ์๊ฐ ์๋ค.
<ul id="crews">
<li id="harry">Harry</li>
<li id="vordt">Vordt</li>
</ul>
๋ง์ฝ ์ด ์ฝ๋์์ ul
์ด ์๋ li
๋ฅผ ํด๋ฆญํ์ ๋๋ง ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๊ณ ์ถ๋ค๋ฉด, ์ด๋ฒคํธ ์์์ ์ฐ์ง ์๋๋ค๋ฉด, li
๋ง๋ค ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํด์ค์ผํ๋ ๋ฒ๊ฑฐ๋ก์ด ์ผ์ด ๋ฐ์ํ๋ค.
๊ทธ๋ฌ๋, ์ด๋ฒคํธ ์์์ ํ์ฉํ๋ฉด ul
์๋ง ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํด์ฃผ๊ณ , ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ด๋ฒคํธ ํ๊น์ด li
์ผ ๋๋ง ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์คํ๋๋๋ก ๋ง์์ฃผ๋ฉด ๋๋ค. ์๋ ์ฝ๋๋ฅผ ํตํด ์ดํด๋ณด์.
$crews.addEventListener('click', handleClickLi());
const handleClickLi = function (e) {
if (!e.target.matches('#crews > li') {
return;
}
...
}
์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ์ ๊ฐ์ผ๋ก ์ง์ ํ ๋ฌธ์์ด์ ์ฌ์ค ์๋ฌต์ ์ผ๋ก ์์ฑ๋๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ๋ฌธ์ด๋ผ๊ณ ํ๋ค. ๋ฐ๋ผ์ handleClick ํจ์๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ํด ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋๋ค.
๋จ, ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํธ์ถํ ๋ ์ธ์๋ก ์ ๋ฌํ this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๋ฅผ ๊ฐ๋ฆฌํจ๋ค. ์ด ๋ handleClick์ ์ ๋ฌํ this๋ ์๋ฌต์ ์ผ๋ก ์์ฑ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ค.
// index.html
<button onClick="handleClick(this)"></button>
// index.js
const handleClick(button) {
console.log(button); // ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์
console.log(this); // window
}
์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์๊ณผ addEventListener ๋ฉ์๋ ๋ฐฉ์ ๋ชจ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๋ฅผ ๊ฐ๋ฆฌํจ๋ค
$harry.onClick = function (e) {
console.log(this); // ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์
}
$harry.addEventListener('click', handleClick());
const handleClick() {
console.log(this); // ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์
}
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์๋ฌต์ ์ผ๋ก ์์ฑ๋๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ๋ฐ์ํ ์ด๋ฒคํธ์ ์ข ๋ฅ์ ๋ฐ๋ผ ์ด๋ฒคํธ ํ์ ์ด ๊ฒฐ์ ๋๋ค. ํ์ง๋ง ์ด๋ฒคํธ ์์ฑ์ ํจ์๋ฅผ ํธ์ถํ์ฌ ๋ช ์์ ์ผ๋ก ์์ฑํ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์์์ ์ด๋ฒคํธ ํ์ ์ ์ง์ ํ ์ ์๋ค. ์ด์ฒ๋ผ ๊ฐ๋ฐ์์ ์๋๋ก ์์ฑ๋ ์ด๋ฒคํธ๋ฅผ ์ปค์คํ ์ด๋ฒคํธ๋ผ ํ๋ค.
const keyboardEvent = new keyboardEvent('keyup');
console.log(keyboradEvent.type); // keyup
const customEvent = new CustomEvent('foo');
console.log(customEvent.type); // foo
์์ฑ๋ ์ปค์คํ ์ด๋ฒคํธ ๊ฐ์ฒด์ bubbles์ cancelable ํ๋กํผํฐ์ ๊ฐ์ด false๋ก ๊ธฐ๋ณธ ์ค์ ๋๋ค. ๊ทธ๋ฌ๋ ์์ฑ์ ํจ์์ ๋ ๋ฒ์งธ ์ธ์๋ก ํ๋กํผํฐ ์ง์ ๊ฐ์ ๊ฐ๋ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ์ฌ ํ๋กํผํฐ ๊ฐ์ ์ง์ ํ ์ ์๋ค.
const customEvent = new MouseEvent('click', {
bubbles: true,
cancelable: true
// ์ด์ธ์๋ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ๊ฐ์ง๋ ๊ณ ์ ์ ํ๋กํผํฐ ๊ฐ์ ์ง์ ํ ์ ์๋ค.
});
๊ทธ๋ฌ๋ ์ด๋ฒคํธ ์์ฑ์ ํจ์๋ก ์์ฑํ ์ปค์คํ ์ด๋ฒคํธ๋ isTrusted ํ๋กํผํฐ์ ๊ฐ์ด ์ธ์ ๋ false์ด๋ค. ๋ฐ๋๋ก ์ฌ์ฉ์์ ํ์์ ์ํด ๋ฐ์ํ ์ด๋ฒคํธ์ ์ํด ์์ฑ๋ ์ด๋ฒคํธ ๊ฐ์ฒด์ isTrusted ํ๋กํผํฐ ๊ฐ์ ์ธ์ ๋ true๋ค.
์์ฑ๋ ์ปค์คํ ์ด๋ฒคํธ๋ dispatchEvent ๋ฉ์๋๋ก ๋์คํจ์น(์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํค๋ ํ์)ํ ์ ์๋ค. dispatchEvent ๋ฉ์๋์ ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์ธ์๋ก ์ ๋ฌํ๋ฉด์ ํธ์ถํ๋ฉด ์ธ์๋ก ์ ๋ฌํ ์ด๋ฒคํธ ํ์ ์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ค.
์ผ๋ฐ์ ์ผ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ฐฉ์์ผ๋ก ๋์ํ์ง๋ง dispatchEvent ๋ฉ์๋๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋๊ธฐ ์ฒ๋ฆฌ ๋ฐฉ์์ผ๋ก ํธ์ถํ๋ค. dispatchEvent ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๊ฒ์ ์ปค์คํ ์ด๋ฒคํธ์ ๋ฐ์ธ๋ฉ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ง์ ํธ์ถํ๋ ๊ฒ๊ณผ ๊ฐ๊ธฐ ๋๋ฌธ์ dispatchEvent ๋ฉ์๋๋ฅผ ํธ์ถํ๊ธฐ ์ด์ ์ ์ปค์คํ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํด์ผํ๋ค.
const $button = document.querySelector('#harry');
const $button2 = document.querySelector('#vordt');
const customEvent = new MouseEvent('click');
const customEvent2 = new CustomEvent('foo', {
detail: { message: 'Hello' },
});
$button.addEventListener('click', e => {
console.log(e);
alert(`${e} Clicked!`);
});
$button2.addEventListener('foo', e => {
alert(e.detail.message);
});
$button.dispatchEvent(customEvent);
$button2.dispatchEvent(customEvent2);
์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ์ฑ๊ธ ์ค๋ ๋๋ก ๋์ํ๋ค. ๊ทธ๋ฌ๋ ๋ธ๋ผ์ฐ์ ๊ฐ ๋์ํ๋ ๊ฒ์ ์ดํด๋ณด๋ฉด ๋ง์ ํ์คํฌ๊ฐ ๋์์ ์ฒ๋ฆฌ๋๋ ๊ฒ์ฒ๋ผ ๋๊ปด์ง๋ค. HTML ์์๊ฐ ์ ๋๋ฉ์ด์ ํจ๊ณผ๋ฅผ ํตํด ์์ง์ด๋ฉด์ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ๋ ํ๊ณ , HTTP ์์ฒญ์ ํตํด ์๋ฒ๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์ค๋ฉด์ ๋ ๋๋งํ๊ธฐ๋ ํ๋ค.
์ด์ฒ๋ผ ์๋ฐ์คํฌ๋ฆฝํธ์ ๋์์ฑ(concurrency)์ ์ง์ํ๋ ๊ฒ์ด ๋ฐ๋ก ๋ธ๋ผ์ฐ์ ์ ๋ด์ฅ๋์ด ์๋ ๊ธฐ๋ฅ ์ค ํ๋์ธ ์ด๋ฒคํธ ๋ฃจํ(event loop)๋ค.
์ด๋ฒคํธ ๋ฃจํ๋ ์ฝ ์คํ์ ํ์ฌ ์คํ ์ค์ธ ์คํ ์ปจํ
์คํธ๊ฐ ์๋์ง, ๊ทธ๋ฆฌ๊ณ ๋น๋๊ธฐ ํจ์์ ์ฝ๋ฐฑ ํจ์๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์ผ์์ ์ผ๋ก ๋ณด๊ด๋๋ ํ์คํฌ ํ์ ๋๊ธฐ ์ค์ธ ํจ์๊ฐ ์๋์ง ๋ฐ๋ณตํด์ ํ์ธํ๋ค.
๋ง์ฝ ์ฝ ์คํ์ด ๋น์ด ์๊ณ ํ์คํฌ ํ์ ๋๊ธฐ ์ค์ธ ํจ์๊ฐ ์๋ค๋ฉด ์ด๋ฒคํธ ๋ฃจํ๋ ์์ฐจ์ ์ผ๋ก ํ์คํฌ ํ์์ ๋๊ธฐ ์ค์ธ ํจ์๋ฅผ ์ฝ ์คํ์ผ๋ก ์ด๋์ํจ๋ค.
์ค๋ช ๋ง์ผ๋ก๋ ์ดํด๊ฐ ํ๋๋ ์์ ์ฝ๋์ ๋์์ ๋ณด๋ฉด์ ์ดํด๋ณด์.
const foo = function () {
console.log('foo');
}
const bar = function () {
console.log('bar');
}
setTimeout(foo, 0);
bar();
์ ์ญ ์ฝ๋๊ฐ ํ๊ฐ๋์ด ์ ์ญ ์คํ ์ปจํ ์คํธ๊ฐ ์์ฑ๋๊ณ ์ฝ ์คํ์ ํธ์๋๋ค.
์ ์ญ ์ฝ๋๊ฐ ์คํ๋์ด setTimeout ํจ์๊ฐ ํธ์ถ๋๋ค. setTimeout ํจ์์ ํจ์ ์คํ ์ปจํ ์คํธ๊ฐ ์์ฑ๋์ด ์ฝ ์คํ์ ํธ์๋๋ค.
setTimeout ํจ์๊ฐ ์คํ๋์ด ์ฝ๋ฐฑ ํจ์๋ฅผ ํธ์ถ ์ค์ผ์ค๋งํ๊ณ ์ข ๋ฃ๋์ด ์ฝ ์คํ์์ ํ๋๋ค. ์ด๋ ํธ์ถ ์ค์ผ์ค๋ง, ์ฆ ํ์ด๋จธ ์ค์ ๊ณผ ํ์ด๋จธ๊ฐ ๋ง๋ฃ๋๋ฉด ์ฝ๋ฐฑ ํจ์๋ฅผ ํ์คํฌ ํ์ ํธ์ํ๋ ๊ฒ์ ๋ธ๋ผ์ฐ์ ์ ์ญํ ์ด๋ค.
๋ธ๋ผ์ฐ์ ๋ ํ์ด๋จธ๋ฅผ ์ค์ ํ๊ณ ํ์ด๋จธ์ ๋ง๋ฃ๋ฅผ ๊ธฐ๋ค๋ฆฐ๋ค. ํ์ด๋จธ๊ฐ ๋ง๋ฃ๋๋ฉด ์ฝ๋ฐฑ ํจ์ foo๊ฐ ํ์คํฌ ํ์ ํธ์๋๋ค. ์ฝ๋ฐฑ ํจ์ foo๋ ํ์ด๋จธ๊ฐ ๋๋๋ ์ฆ์ ์คํ๋์ง ์๊ณ ์ฝ ์คํ์ด ๋น์์ง ๋๊น์ง ํ์คํฌ ํ์์ ๋๊ธฐํ๋ค.
bar ํจ์์ ์คํ๊น์ง ๋๋๊ณ ์ ์ญ ์ฝ๋ ์คํ์ด ๋๋๊ณ ์ ์ญ ์คํ ์ปจํ ์คํธ๊ฐ ์ฝ ์คํ์์ ํ๋๋ฉด ์ด๋ฒคํธ ๋ฃจํ์ ์ํด ์ฝ ์คํ์ด ๋น์ด ์์์ด ๊ฐ์ง๋๊ณ ํ์คํฌ ํ์์ ๋๊ธฐ ์ค์ธ foo๊ฐ ์ด๋ฒคํธ ๋ฃจํ์ ์ํด ์ฝ ์คํ์ ํธ์๋๋ค.