
ํ๋ก ํธ์๋ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํ โ์ด๋ฒคํธ ์์โ ์ ๋ต
ํ๋ก ํธ์๋ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํ โ์ด๋ฒคํธ ์์โ ์ ๋ต ๊ด๋ จ
ํ๋ก ํธ์๋ ๊ฐ๋ฐ์ ํ๋ค ๋ณด๋ฉด ๋งํฌ์ ์ด ์ ์ ๋ณต์กํด์ง๊ณ , ์ฌ์ฉ์ ์ธํฐ๋์ ์ด ๋์ด๋จ์ ๋ฐ๋ผ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ํจ๊ป ๋์ด๋๋ ํ์์ ์์ฃผ ๊ฒช๊ฒ ๋ฉ๋๋ค. ํนํ ๋๊ท๋ชจ UI๋ฅผ ๋ค๋ฃจ๊ฑฐ๋, ๋ฐ๋ณต๋๋ DOM ๊ตฌ์กฐ๋ฅผ ํฌํจํ๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ๋ฒํผ ์์ญ ๊ฐ, ๋ฆฌ์คํธ ์๋ฐฑ ๊ฐ์ ์ด๋ฒคํธ๋ฅผ ๊ฐ๊ฐ ๋ฑ๋กํด์ผ ํ ์ง๋ ๋ชจ๋ฆ ๋๋ค. ์ด์ฒ๋ผ ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ๋ง์์ง๋ฉด ๋จ์ํ ๋ฉ๋ชจ๋ฆฌ ์๋น๊ฐ ๋์ด๋๋ ๊ฒ์ ๋์ด, ๋ ๋๋ง ์ฑ๋ฅ ์ ํ, ์ ์ง๋ณด์์ ์ด๋ ค์์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ๋ํ์ ์ธ ํจํด์ด ๋ฐ๋ก ์ด๋ฒคํธ ์์(Event Delegation)์ ๋๋ค.

์ด๋ฒคํธ ์์์ ์ด๋ฒคํธ ๋ฒ๋ธ๋ง ํน์ฑ์ ํ์ฉํ์ฌ, ์ฌ๋ฌ ๊ฐ์ ํ์ ์์ ๊ฐ๊ฐ์ ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํ๋ ๋์ ์์ ์์ ํ๋์๋ง ๋ฆฌ์ค๋๋ฅผ ๊ฑธ์ด ํจ์จ์ ์ผ๋ก ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ ๋๋ค.
์ด๋ฒ ๊ธ์์๋ ์ด๋ฒคํธ ์์์ด ์ด๋ป๊ฒ ๋์ํ๋์ง, ์ค์ ๋ก๋ ์ด๋ค ์ฅ์ ์ ์ ๊ณตํ๋์ง, ๊ทธ๋ฆฌ๊ณ ์ธ์ ์์์ ์ฐ๊ณ ์ธ์ ์ง์ ๋ฑ๋กํ๋ ๊ฒ์ด ๋ ๋์์ง์ ๋ํด ์ค๋ฌด์ ์ธ ๊ด์ ์์ ๊ตฌ์ฒด์ ์ธ ์์์ ํจ๊ป ์์๋ณด๊ฒ ์ต๋๋ค.
์ด๋ฒคํธ ์์์ด๋?
์ด๋ฒคํธ ์์์ ์ด๋ฒคํธ ์ฒ๋ฆฌ๋ฅผ โ์์ํ๋คโ๋ผ๋ ๊ฐ๋ ์ผ๋ก, ์์ ์์๊ฐ ์๋ ๊ณตํต ๋ถ๋ชจ ์์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํด, ํ์ ์์์ ์ด๋ฒคํธ๊น์ง ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ ๋๋ค. ๋ฐ๋ณต๋๋ ๊ตฌ์กฐ๋ ๋์ ์ผ๋ก ์์ฑ๋๋ ์์๊ฐ ๋ง์ ๋ ํนํ ์ ์ฉํ๋ฉฐ, DOM ์ด๋ฒคํธ์ ๋ฒ๋ธ๋ง ๋๋ถ์ ๊ฐ๋ฅํ ์ ๋ต์ ๋๋ค.
1. ์์ ์์์ ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํด ํ์ ์์๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ์
์๋ฅผ ๋ค์ด, <ul>
ํ๊ทธ ์์ ์์ญ ๊ฐ์ <li>
ํญ๋ชฉ์ด ์๋ค๊ณ ํด๋ด
์๋ค.

๊ฐ <li>
์ ์ผ์ผ์ด ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ๋ถ์ด๋ ๋์ , ์์ ์์์ธ <ul>
์ ๋จ ํ๋์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ง ๋ฑ๋กํ๊ณ , ํด๋ฆญ ๋ ๋์์ด ์ด๋ค <li>
์ธ์ง ํ๋จํ์ฌ, ์ ์ ํ ๋์์ ์ํํ๋๋ก ๋ง๋๋ ๋ฐฉ์์ด์ฃ .
const ul = document.querySelector("ul");
ul.addEventListener("click", (e) => {
if (e.target.tagName === "LI") {
console.log(`ํด๋ฆญ๋ ํญ๋ชฉ: ${e.target.textContent}`);
}
});
์ฌ๊ธฐ์ e.target.tagName
์ ๋๋ฌธ์๋ก ๋ฐํ๋๊ธฐ ๋๋ฌธ์ โLIโ์ ๋น๊ตํฉ๋๋ค. ์๋ฌธ์ โliโ๋ก ๋น๊ตํ๋ฉด ์กฐ๊ฑด์ด ํญ์ false๊ฐ ๋๊ธฐ ๋๋ฌธ์ ์ฃผ์ํด์ผ ํฉ๋๋ค.
์กฐ๊ธ ๋ ์ค์ ์ ์ธ ์์๋ก, ์ผํ๋ชฐ ์ํ ๋ชฉ๋ก์์ .delete-button
ํด๋์ค๊ฐ ์๋ ์ญ์ ๋ฒํผ์ ์ฒ๋ฆฌํด ๋ณด๊ฒ ์ต๋๋ค.
document.querySelector('#product-list').addEventListener('click', (e) => {
if (e.target.matches('.delete-button')) {
console.log('์ญ์ ๋จ');
}
});
์ด ์ฝ๋์์๋ .delete-button
ํด๋์ค๋ฅผ ๊ฐ์ง ๋ฒํผ์ ํด๋ฆญํ์ ๋๋ง ์ด๋ฒคํธ๊ฐ ๋์ํ๋๋ก e.target.matches()
๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์์ ์์์ธ #product-list
์ ์ด๋ฒคํธ๋ฅผ ํ ๋ฒ๋ง ๋ฑ๋กํด๋, ํ์์ ์๋ ์๋ง์ ์ญ์ ๋ฒํผ๋ค์ ํ ๋ฒ์ ์ ์ดํ ์ ์์ต๋๋ค.
2. ์ด๋ฒคํธ ๋ฒ๋ธ๋ง์ด๋?
์ด๋ฒคํธ ์์์ ๊ธฐ๋ฐ์ด ๋๋ ๊ฐ๋ ์ด ๋ฐ๋ก ์ด๋ฒคํธ ๋ฒ๋ธ๋ง์ ๋๋ค. ์ด๋ฒคํธ ๋ฒ๋ธ๋ง(Event Bubbling)์ DOM ์์์์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋, ํด๋น ์ด๋ฒคํธ๊ฐ DOM ํธ๋ฆฌ๋ฅผ ๋ฐ๋ผ ์์ ์์๋ก ์์ฐจ์ ์ผ๋ก ์ ํ๋๋ ํ์์ ๋งํฉ๋๋ค.
์๋ฅผ ๋ค์ด, ์์ ์์๋ฅผ ํด๋ฆญํ๋ฉด ํด๋ฆญ ์ด๋ฒคํธ๋ li
์์์์ ๋ฐ์ํ ๋ค, ul
, body
, html
, document
์์ผ๋ก ์ ๋ฌ๋ฉ๋๋ค. ์ด ๊ตฌ์กฐ ๋๋ถ์ ํ์ ์์์์ ๋ฐ์ํ ์ด๋ฒคํธ๋ฅผ ์์ ์์์์๋ ๊ฐ์งํ ์ ์๋๋ฐ์. ์ด๊ฒ์ด ๋ฐ๋ก ์ด๋ฒคํธ ์์์ด ๊ฐ๋ฅํด์ง๋ ์ด์ ์
๋๋ค. ์๋์ ๊ฐ์ HTML ๊ตฌ์กฐ๋ฅผ ์๋ก ๋ค์ด๋ณผ๊ฒ์.
<ul id="menu">
<li class="item">ํ</li>
<li class="item">์๊ฐ</li>
<li class="item">๋ฌธ์</li>
</ul>
์ด ๋ฆฌ์คํธ์์ ๊ฐ๊ฐ์ <li class=โitemโ>
์ ๊ฐ๋ณ ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํ๋ ๋์ , ๋ค์๊ณผ ๊ฐ์ด <ul id=โmenuโ>
ํ๋์๋ง ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํ ์ ์์ต๋๋ค.
document.getElementById('menu').addEventListener('click', (e) => {
const li = e.target.closest('.item');
if (li) {
console.log(`ํด๋ฆญํ ํญ๋ชฉ: ${li.textContent}`);
}
});
์ด๋ฒคํธ๋ ์ค์ ๋ก๋ <li>
์์์์ ๋ฐ์ํ์ง๋ง, ์ด ์ด๋ฒคํธ๊ฐ ๋ถ๋ชจ์ธ <ul>
๊น์ง ์ ํ๋๊ธฐ ๋๋ฌธ์ <ul>
์์ ๊ฐ์งํ๊ณ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. closest()
๋ฉ์๋๋ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์์น์์ ๊ฐ์ฅ ๊ฐ๊น์ด .item
ํด๋์ค๋ฅผ ๊ฐ์ง ์์ ์์๋ฅผ ์ฐพ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์ด๋ฌํ ๋ฐฉ์์ ์ฝ๋์ ๊ฐ๊ฒฐ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์ด๋ ๋ฐ ํฐ ๋์์ด ๋์ฃ .
์ด๋ฒคํธ ์์์ ์ฅ์
๋ํ ์ด๋ฒคํธ ์์์ ๋จ์ํ ์ด๋ฒคํธ ๋ฑ๋ก ์๋ฅผ ์ค์ด๋ ๊ธฐ์ ์ด ์๋๋๋ค. ์ฑ๋ฅ, ์ ์ง๋ณด์, ํ์ฅ์ฑ ์ธก๋ฉด์์๋ ๋ค์ํ ์ด์ ์ ์ ๊ณตํฉ๋๋ค.
1. ๋ฐ๋ณต ๊ตฌ์กฐ์์ ํธ๋ค๋ฌ ์ ๋ํญ ๊ฐ์
์ด๋ฒคํธ ์์์ ๊ฐ์ฅ ํฐ ๊ฐ์ ์ค ํ๋๋ ๋ฐ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์๋ฅผ ๋ํญ ์ค์ผ ์ ์๋ค๋ ์ ์ ๋๋ค. ๋ฐ๋ณต๋๋ UI ๊ตฌ์กฐ์์ ๊ฐ ์์๋ง๋ค ์ผ์ผ์ด ํธ๋ค๋ฌ๋ฅผ ๋ถ์ด๋ ๋ฐฉ์์ ๋ธ๋ผ์ฐ์ ๋ฉ๋ชจ๋ฆฌ์ ๋ถ๋ด์ ์ค ์ ์๊ณ , ์ฝ๋๋ ๋ถํ์ํ๊ฒ ๊ธธ์ด์ง๊ธฐ ๋ง๋ จ์ ๋๋ค. ์ด์ ๋ฌ๋ฆฌ ์ด๋ฒคํธ ์์์ ํ์ฉํ๋ฉด ์์ญ, ์๋ฐฑ ๊ฐ์ ์์๋ ๋จ ํ ์ค์ ํธ๋ค๋ฌ๋ก ํตํฉํด์ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.

์๋ฅผ ๋ค์ด, ๋๊ธ ๋ชฉ๋ก์ด๋ ์ผํ๋ชฐ์ ์ํ ์นด๋์ฒ๋ผ ์๋ง์ ํญ๋ชฉ์ด ๋ฐ๋ณต๋๋ UI์์๋ ๊ฐ ์์์ ํธ๋ค๋ฌ๋ฅผ ๋ถ์ด๋ ๊ฒ๋ณด๋ค, ์์ ์ปจํ ์ด๋์ ํ๋์ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ ํธ์ด ํจ์ฌ ํจ์จ์ ์ ๋๋ค.
2. ๋์ ์ผ๋ก ์์ฑ๋ ์์์์๋ ์๋ ์ ์ฉ
๋ ๋ค๋ฅธ ์ฅ์ ์ ๋์ ์ผ๋ก ์์ฑ๋๋ ์์์๋ ๋ณ๋์ ํธ๋ค๋ฌ๋ฅผ ๋ถ์ด์ง ์์๋ ์๋์ผ๋ก ๋์ํ๋ค๋ ์ ์ ๋๋ค. ๋ค์ ์์ ๋ฅผ ๋ณด์๋ฉด ์ดํดํ๊ธฐ ์ฌ์ธ ๊ฒ๋๋ค.
document.getElementById('todo-list').addEventListener('click', (e) => {
if (e.target.matches('.todo-delete')) {
e.target.parentElement.remove();
}
});
const newItem = document.createElement('li');
newItem.innerHTML = '์ ํ ์ผ <button class="todo-delete">์ญ์ </button>';
document.getElementById('todo-list').appendChild(newItem);
์ด ์ฝ๋๋ ๊ธฐ์กด์ ๋ฑ๋ก๋ ํธ๋ค๋ฌ๋ก ์๋ก ์ถ๊ฐ๋ .todo-delete
๋ฒํผ๊น์ง ์ ์ดํ ์ ์์ต๋๋ค. appendChild๋ก ์๋กญ๊ฒ ์์ฑ๋ ์์์๋ ๊ฐ๋ณ ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํ์ง ์์์ง๋ง, ์์ ์์์ ๋ฑ๋ก๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์ ์์ ์ผ๋ก ๋์ํ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ์ด์ฒ๋ผ ๋์ UI์์ ์ด๋ฒคํธ ์์์ ์ ์ง๋ณด์์ ์ฑ๋ฅ ์ธก๋ฉด์์ ๋งค์ฐ ์ ๋ฆฌํ ์ ๋ต์
๋๋ค.
์ธ์ ์ด๋ฒคํธ ์์์ ์ฐ๊ณ , ์ธ์ ์ง์ ๋ฑ๋กํ ๊น?
์ด๋ฒคํธ ์์์ ๋ง์ ์ํฉ์์ ์ ์ฉํ์ง๋ง, ๋ชจ๋ ๊ณณ์ ๋ฌด์กฐ๊ฑด ์ ์ฉํ ์ ์๋ ๋ง๋ฅ ๋๊ตฌ๋ ์๋๋๋ค. ์ํฉ์ ๋ฐ๋ผ ์ ์ ํ ์์๊ณผ ์ง์ ๋ฑ๋ก ๋ฐฉ์์ ๊ตฌ๋ถํด์ผ ํฉ๋๋ค.
1. ๋ฐ๋ณต๋๋ ๊ตฌ์กฐ์์๋ ์ด๋ฒคํธ ์์
<ul>
, <table>
, <div class=โgridโ>
์ฒ๋ผ ๋์ผํ ๊ตฌ์กฐ๊ฐ ๋ฐ๋ณต๋๋ ๊ฒฝ์ฐ๋ผ๋ฉด ์ด๋ฒคํธ ์์์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์์ญ ๊ฐ ์ด์์ ์์์ ๋์ผํ ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํด์ผ ํ ๋๋ ์์ ๋ฐฉ์์ด ๊ฑฐ์ ํ์์
๋๋ค. ํนํ ๋ฆฌ์คํธ ํญ๋ชฉ์ด๋ ๊ฒ์๊ธ ๋ชฉ๋ก, ๋๊ธ UI์ฒ๋ผ ๋์ ์์๊ฐ ๋ฐ๋ณต๋๋ ๊ฒฝ์ฐ ์์ ๋ฐฉ์์ ์ฑ๋ฅ๊ณผ ์ ์ง๋ณด์ ์ธก๋ฉด ๋ชจ๋์์ ํ์ํ ์ ํ์
๋๋ค.
2) ๋จ์ผ ๋๋ ์ค์ํ ์ธํฐ๋์ ์ ์ง์ ๋ฑ๋ก
๋ฐ๋ฉด, submit
, scroll
, drag
, touchmove
์ ๊ฐ์ ์ด๋ฒคํธ๋ ์๊ธฐ์น ์์ ์ ํ๋ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ๋ง๊ธฐ ์ํด ์ง์ ๋ฑ๋กํ๋ ๊ฒ์ด ๋ ์์ ํฉ๋๋ค. ๋ก๊ทธ์ธ, ๊ฒฐ์ , ๋ณด์ ๊ด๋ จ ์ด๋ฒคํธ์ฒ๋ผ ๋ฐ๋์ ์๋ํ ๋์์์๋ง ๋์ํด์ผ ํ๋ ์ด๋ฒคํธ๋ ๋ง์ฐฌ๊ฐ์ง์
๋๋ค. ์ด ๊ฒฝ์ฐ ์ด๋ฒคํธ ์์๋ณด๋ค๋ ๋ช
ํํ๊ฒ ํด๋น ์์์ ์ง์ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ ๊ฒ์ด ๋ ๋ฐ๋์งํฉ๋๋ค.
3) ๋ฒ๋ธ๋ง์ด ์ค๋จ๋๋ ๊ตฌ์กฐ์์๋ ์์์ด ์ด๋ ค์
์ด๋ฒคํธ ๋ฒ๋ธ๋ง์ด ๋์ค์ ์ค๋จ๋๋ ๊ตฌ์กฐ์์๋ ์์์ด ์ ๋๋ก ์๋ํ์ง ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, stopPropagation()
์ด ํธ์ถ๋๊ฑฐ๋, Shadow DOM ๊ฐ์ ์บก์ํ๋ ํ๊ฒฝ์์๋ ์ด๋ฒคํธ๊ฐ ์์ ์์๊น์ง ์ ํ๋์ง ์๊ธฐ ๋๋ฌธ์ ์ด๋ฒคํธ ์์ ๋ฐฉ์์ด ๋ฌด๋ ฅํ๋ ์ ์์ต๋๋ค. ์ด๋ด ๋ ์์์ด ์๋ ์ง์ ์ด๋ฒคํธ ๋ฑ๋ก ๋ฐฉ์์ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
๋ง์น๋ฉฐ
๋๊ท๋ชจ UI๋ฅผ ๋ค๋ฃฐ ๋, ๋ฐ๋ณต๋๋ DOM ๊ตฌ์กฐ๋ ๋์ ์ผ๋ก ์์ฑ๋๋ ์์๊ฐ ๋ง๋ค๋ฉด, ์ด๋ฒคํธ ์์์ ๋งค์ฐ ์ ์ฉํ ์ ๋ต์ ๋๋ค. ํธ๋ค๋ฌ ์๋ฅผ ์ค์ด๊ณ ์ฑ๋ฅ์ ๊ฐ์ ํ ์ ์์ ๋ฟ๋ง ์๋๋ผ, ์ฝ๋ ์ ์ง๋ณด์์ ํ์ฅ์ฑ ์ธก๋ฉด์์๋ ๋ฐ์ด๋ ์ด์ ์ ์ ๊ณตํฉ๋๋ค. ๋ฌผ๋ก ๋ชจ๋ ์ํฉ์ ์ ์ฉ๋๋ ๊ฒ์ ์๋๋ฏ๋ก, ์ด๋ฒคํธ ์ ํ ๊ตฌ์กฐ๋ UI์ ํน์ฑ์ ๋ฐ๋ผ ์์๊ณผ ์ง์ ๋ฑ๋ก์ ์ ์ ํ ์กฐํฉํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
๋ง์ง๋ง์ผ๋ก, ํฌ๋กฌ ๊ฐ๋ฐ์ ๋๊ตฌ์ Performance์ Memory ํญ์ ํ์ฉํด, ์ด๋ฒคํธ ํธ๋ค๋ฌ ์, ์คํ ์๊ฐ, GC ์ํ ๋ฑ์ ์ฃผ๊ธฐ์ ์ผ๋ก ์ ๊ฒํด ๋ณด๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ฐ๋ฆฌ๊ฐ ๋ฌด์ฌ์ฝ ๋ถ์ธ ์ด๋ฒคํธ ํ๋๊ฐ ์ฑ ์ฑ๋ฅ์ ํฐ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค. ์ฌ๋ฐ๋ฅธ ์ ๋ต์ผ๋ก ์ด๋ฒคํธ๋ฅผ ๋ค๋ฃจ๋ ์ต๊ด์ด ์์ผ์๋ก, ๋์ฑ ๋น ๋ฅด๊ณ ์์ ์ ์ธ ํ๋ก ํธ์๋ ๊ฐ๋ฐ์ด ๊ฐ๋ฅํด์ง ๊ฒ์ ๋๋ค.