์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ๋ก ๋ฐฉ๋ฒ
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ๋ธ๋ผ์ฐ์ ์ ์ํด ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ๋ฑ๋ก๋ ํจ์๊ฐ ํธ์ถ๋ฉ๋๋ค.
์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ์ ํฌ๊ฒ 3๊ฐ์ง๊ฐ ์์ต๋๋ค.
1. ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๋ฐฉ์
HTML ์์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๊ฐ์ผ๋ก ํจ์ ํธ์ถ๋ฌธ์ ํ ๋นํ๋ ๋ฐฉ์์ ๋๋ค.
<button onclick="sayHi('Lee')">Click me!</button>
<script>
function sayHi(name) {
console.log(`Hi! ${name}.`);
}
</script>
์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๊ฐ์ ์ฌ์ค ์๋ฌต์ ์ผ๋ก ์์ฑ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ํจ์ ๋ชธ์ฒด๋ฅผ ์๋ฏธํฉ๋๋ค.
function onclick(event) {
sayHi('Lee')
}
// ์ด๋ฐ ํจ์๊ฐ ์๋ฌต์ ์ผ๋ก ์์ฑ๋์ด ์์์ onclick ํ๋กํผํฐ์ ๋ฐ์ธ๋ฉ๋ฉ๋๋ค.
์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๋ฐฉ์์ HTML๊ณผ JS๊ฐ ํผ์ฌํ๋ฏ๋ก ๊ถ์ฅ๋์ง ์์ต๋๋ค.
๋๋ถ๋ถ์ ํ๋ ์์ํฌ/๋ผ์ด๋ธ๋ฌ๋ฆฌ(React, Vue, Angular, Svelte ๋ฑ)๋ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ๊ฐ๋ฐ(CBD)์์ ์ด๋ฅผ ํผํ๊ณ , ๊ตฌ์กฐ์ ์ผ๋ก HTML๊ณผ JS๋ฅผ ๋ถ๋ฆฌํ์ฌ ์ฌ์ฉํฉ๋๋ค.
2. ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์
DOM ์์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ์ง์ ํจ์๋ฅผ ๋ฐ์ธ๋ฉํ๋ ๋ฐฉ์์ ๋๋ค.
const $button = document.querySelector('button');
$button.onclick = function() {
console.log('button click');
};
์ด ๋ฐฉ์์ HTML๊ณผ JS๋ฅผ ๋ถ๋ฆฌํ ์ ์๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
ํ์ง๋ง ๋จ์ ์ ํ๋์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ง ๋ฐ์ธ๋ฉํ ์ ์๋ค๋ ์ ์
๋๋ค.
3. addEventListener ๋ฉ์๋ ๋ฐฉ์
addEventListener ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋ ์ด์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ์ ์์ต๋๋ค.
EventTarget.addEventListener('eventType', handler, [, useCapture]);
$button.addEventListener('click', function() {
console.log('button click');
});
ํน์ง์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ํ๋ ์ด์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ์ ์์ต๋๋ค.
- ๋ฑ๋ก๋ ์์๋๋ก ํธ์ถ๋ฉ๋๋ค.
- ๋์ผํ ์ฐธ์กฐ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ค๋ณต ๋ฑ๋กํ๋ฉด ํ๋๋ง ๋ฑ๋ก๋ฉ๋๋ค.
- useCapture ์ต์ ์ ํตํด ์บก์ฒ๋ง ๋จ๊ณ์์๋ ์ด๋ฒคํธ๋ฅผ ์ก์๋ผ ์ ์์ต๋๋ค.
์ด๋ฒคํธ ์ ํ
ํน์ DOM ๋
ธ๋์์ ๋ฐ์ํ ์ด๋ฒคํธ๋ DOM ํธ๋ฆฌ๋ฅผ ํตํด ์ ํ๋ฉ๋๋ค.
์ด๋ฒคํธ ์ ํ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์ ๋ฌ๋๋ ๋ฐฉํฅ์ ๋ฐ๋ผ 3๋จ๊ณ๋ก ๋๋ ์ ์์ต๋๋ค.
- ์บก์ฒ๋ง ๋จ๊ณ : ์ด๋ฒคํธ๊ฐ ์์ ์์์์ ํ์ ์์๋ก ์ ํ๋ฉ๋๋ค.
- ํ๊น ๋จ๊ณ : ์ด๋ฒคํธ๊ฐ ์ค์ ํ๊น ์์์ ๋๋ฌํฉ๋๋ค.
- ๋ฒ๋ธ๋ง ๋จ๊ณ : ์ด๋ฒคํธ๊ฐ ํ์ ์์์์ ์์ ์์๋ก ์ ํ๋ฉ๋๋ค.

์ด๋ฒคํธ ๋ฒ๋ธ๋ง ๋๋ถ์ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ ํ๊น๋ฟ ์๋๋ผ ์์ DOM ์์์์๋ ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ ์ ์์ต๋๋ค.
์ด๋ฅผ ํ์ฉํ ๊ฒ์ด ๋ฐ๋ก ์ด๋ฒคํธ ์์์
๋๋ค.
๋จ, focus/blur, mouseenter/mouseleave์ ๊ฐ์ ๋ช๋ช ์ด๋ฒคํธ๋ ๋ฒ๋ธ๋ง๋์ง ์์ต๋๋ค.
์ด๋ฒคํธ ์บก์ฒ๋ง๊ณผ ๋ฒ๋ธ๋ง ์์
<body>
<p><button>๋ฒํผ</button></p>
<script>
document.body.addEventListener('click', () => {
console.log("handler for body");
}); // ๋ฒ๋ธ๋ง ๋จ๊ณ
const p = document.querySelector('p');
p.addEventListener('click', () => {
console.log("handler for p");
}, true); // ์บก์ฒ๋ง ๋จ๊ณ
const button = document.querySelector('button');
button.addEventListener('click', () => {
console.log("handler for button");
}); // ํ๊น ๋จ๊ณ
</script>
</body>
์คํ ๊ฒฐ๊ณผ ์์
- "handler for p" (์บก์ฒ๋ง ๋จ๊ณ)
- "handler for button" (ํ๊น ๋จ๊ณ)
- "handler for body" (๋ฒ๋ธ๋ง ๋จ๊ณ)
์ด๋ฒคํธ ์ ํ ๋ฐฉ์ง
์ด๋ฒคํธ๊ฐ ์์ ์์๋ก ์ ํ๋๋ ๊ฒ์ ๋ง๊ณ ์ถ์ ๋๋ stopPropagation()์ ์ฌ์ฉํฉ๋๋ค.
e.stopPropagation();
์ด๋ฒคํธ ์์
์ด๋ฒคํธ ์์์ด๋, ์ฌ๋ฌ ํ์ DOM ์์์ ๊ฐ๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ์ง ์๊ณ , ์์ ์์์ ํ๋์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ์ฌ ํจ์จ์ ์ผ๋ก ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ ๋๋ค.
- ์ด๋ฒคํธ๋ ๋ฒ๋ธ๋ง์ ํตํด ์์ ์์๋ก ์ ํ๋๋ฏ๋ก, ์์ ์์์์ ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ ์ ์์ต๋๋ค.
- ํ์ง๋ง ์ด๋ ์ฃผ์ํ ์ ์, ์ด๋ฒคํธ ํ๊น์ด ํญ์ ๊ธฐ๋ํ DOM ์์์ผ ํ์๋ ์๋ค๋ ๊ฒ์ ๋๋ค. ๋ฐ๋ผ์ event.target์ ๊ฒ์ฌํ๊ฑฐ๋ closest()๋ฅผ ํ์ฉํด์ผ ํฉ๋๋ค.
์์:
document.addEventListener('click', (e) => {
const li = e.target.closest('li');
if (!li) return;
console.log('ํด๋ฆญ๋ ์์:', li.textContent);
});
์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this
- ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๋ฐฉ์
- ํจ์ ๋ด๋ถ์ this๋ ์ ์ญ ๊ฐ์ฒด(window)๋ฅผ ๊ฐ๋ฆฌํต๋๋ค.
- ๋์ this๋ฅผ ์ธ์๋ก ์ ๋ฌํ๋ฉด ํด๋น DOM ์์๋ฅผ ์ง์ ์ฐธ์กฐํ ์ ์์ต๋๋ค.
<button onclick="handleClick(this)">๋ฒํผ</button>
<script>
function handleClick(that){
console.log(this); // window
console.log(that); // <button>
}
</script>
- ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์๊ณผ addEventListener ๋ฐฉ์
- ํจ์ ๋ด๋ถ์ this๋ ์ด๋ฒคํธ๊ฐ ๋ฐ์ธ๋ฉ๋ ์์๋ฅผ ๊ฐ๋ฆฌํต๋๋ค.
- ์ด๋ event.currentTarget๊ณผ ๋์ผํฉ๋๋ค.
$button.onclick = function(e) {
console.log(this); // $button
console.log(e.currentTarget); // $button
};
์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ธ์ ์ ๋ฌ
์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ง์ ์ธ์๋ฅผ ์ ๋ฌํ๊ณ ์ถ์ ๋๋, ๋ณดํต ๋ํผ ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค.
const checkUserNameLength = min => {...};
$input.onblur = () => { checkUserNameLength(5); };
ํน์ ํจ์๋ฅผ ๋ฐํํ๋ ํจ์๋ฅผ ํ์ฉํ์ฌ ๋ฐ์ธ๋ฉํ ์ ์์ต๋๋ค.
๋ง๋ฌด๋ฆฌ
์ด๋ฒคํธ ์์คํ ์ ๋ธ๋ผ์ฐ์ ๊ฐ DOM ํธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ๊ณ , ์ฑ๋ฅ์ ์ต์ ํํ๊ธฐ ์ํด ์ค๊ณ๋ ์ค์ํ ๋ฉ์ปค๋์ฆ์ ๋๋ค.
- ์ด๋ฒคํธ ์ ํ(์บก์ฒ๋ง/๋ฒ๋ธ๋ง) ๋ฅผ ํตํด ์์ ์์์ ํ์ ์์ ๋ชจ๋ ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ ์ ์์ต๋๋ค.
- ์ด๋ฅผ ์์ฉํ ์ด๋ฒคํธ ์์์ ์ฑ๋ฅ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์ฌ์ค๋๋ค.
- ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ๋ก ๋ฐฉ์์๋ ์ดํธ๋ฆฌ๋ทฐํธ, ํ๋กํผํฐ, addEventListener ๋ฐฉ์์ด ์์ผ๋ฉฐ, ์ค๋ฌด์์๋ addEventListener๋ฅผ ๊ถ์ฅํฉ๋๋ค.
'๐ ํ๋ก ํธ์๋(FE)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| Webpack + Babel + TypeScript ์ค์ ๊ฐ์ด๋ (0) | 2025.09.16 |
|---|---|
| MVC ๊ตฌ์กฐ - ์ต์ ๋ฒ ํจํด ( Observer Pattern ) (0) | 2025.09.08 |
| [CoderPad] ๋ฆฌ์กํธ ๊ฐ์ ์คํฌ๋กค (Virtualized List) (5) | 2025.06.22 |
| Next.js 12 ์์ React Query v4 + SSR ํ์ฉํ๊ธฐ (0) | 2025.05.01 |
| ์น ํ๋ก ํธ์๋ ํด๋ฆฐ ์ํคํ ์ณ(Clean Architecture) ์ ์ญ์ฌ (0) | 2025.04.29 |