✨ 프론트엔드 필수 개념: 이벤트 위임과 이벤트 버블링 정리
웹에서 리스트나 버튼 같은 반복적인 요소에 이벤트를 걸어야 할 때, 매번 하나하나 이벤트 리스너를 붙이는 것은 비효율적입니다. 이럴 때 사용할 수 있는 똑똑한 방법이 바로 이벤트 위임(Event Delegation)입니다.
이번 글에서는 이벤트 위임이란 무엇인지, 이 개념이 가능한 이유인 이벤트 버블링(Event Bubbling)까지 함께 정리해보겠습니다.
✅ 이벤트 위임(Event Delegation)이란?
이벤트 위임은 여러 자식 요소 각각에 이벤트 리스너를 다는 대신, 공통된 부모 요소에 하나의 이벤트 리스너를 등록해서 이벤트를 처리하는 방식입니다.
즉, 부모가 자식의 이벤트를 '위임'받는 형태라고 볼 수 있습니다. 예를 들어 <ul> 태그 안에 <li> 요소가 여러 개 있을 때, 각각의 <li>에 addEventListener를 다는 것이 아니라, 상위 요소인 <ul>에 이벤트를 하나만 등록하여 처리합니다.
🧠 이벤트 위임이 필요한 이유
- 성능 향상: 수백 개의 요소에 각각 이벤트를 다는 것은 리소스를 많이 소모합니다. 부모 요소 하나에만 이벤트를 걸면 성능이 향상됩니다.
- 동적 요소 대응: 자바스크립트로 새롭게 생성되는 요소들도 자동으로 이벤트 처리가 가능합니다.
- 유지보수 용이: 이벤트 로직을 하나의 위치에서 관리할 수 있으므로 코드가 깔끔하고 수정도 쉽습니다.
💡 예시 코드로 살펴보기
❌ 각 요소에 직접 이벤트를 다는 방식
document.querySelectorAll('#menu li').forEach((li) => {
li.addEventListener('click', () => {
console.log(li.textContent);
});
});
- 반복문으로 각각의 요소에 리스너를 붙여야 합니다.
- *나중에 <li>가 추가되면 이벤트가 동작하지 않습니다.
✅ 이벤트 위임 방식
document.getElementById('menu').addEventListener('click', (event) => {
if (event.target.tagName === 'LI') {
console.log(event.target.textContent);
}
});
- 부모 요소 하나에만 이벤트를 등록합니다.
- 이후 <li>가 추가되어도 이벤트가 자동으로 적용됩니다.
(+) Q. 왜 새로 추가된 <li>에는 이벤트가 안 붙을까요?
위에서 각 요소에 직접 이벤트를 다는 방식의 코드는
querySelectorAll로 현재 존재하는 <li>들을 모두 선택해서, 그 각각에 대해 click 이벤트를 등록합니다.
그런데 이때 핵심은:
이벤트 리스너는 '그 시점'에 존재하는 요소에만 붙는다는 점입니다.
- 그 이후에 JS로 새로운 <li>를 추가하면?
- 그 새 <li>는 이벤트 리스너를 따로 안 붙였기 때문에 클릭해도 반응하지 않습니다.
그래서 이 문제의 해결책으로 "이벤트 위임"이 되는 것입니다.
부모 요소(<ul id="menu">)에 딱 한 번만 이벤트를 걸어두고, 이벤트 버블링을 통해 자식 <li>의 클릭을 감지할 수 있어요.
요약
비교 | 직접 이벤트 부착 | 이벤트 위임 |
대상 | 현재 존재하는 요소만 | 부모 요소 하나 |
새로 추가된 요소 | ❌ 이벤트 없음 | ✅ 자동 적용 |
유지보수 | 번거롭고 반복적 | 깔끔하고 확장성 있음 |
📌 이벤트 위임의 원리: 이벤트 버블링(Event Bubbling)
이벤트 위임이 가능한 이유는 이벤트 버블링이라는 자바스크립트의 이벤트 전파 방식 때문입니다.
브라우저에서 이벤트가 발생하면, 해당 요소에서 시작하여 부모 → 조상 → 최상단(document)까지 순차적으로 이벤트가 전달됩니다. 이를 버블링(Bubbling)이라고 부르며, 마치 거품이 위로 올라가는 것처럼 동작합니다.
이 덕분에 우리는 부모 요소에 이벤트를 등록하고, event.target을 통해 실제로 이벤트가 발생한 자식 요소를 찾아낼 수 있습니다.
🧪 event.target vs event.currentTarget 차이
- event.target: 실제 클릭된 요소입니다.
- event.currentTarget: 이벤트가 바인딩된 요소(예: <ul> 등)입니다.
ul.addEventListener('click', (event) => {
console.log('클릭한 요소:', event.target);
console.log('이벤트 바인딩된 요소:', event.currentTarget);
});
✅ 이벤트 위임이 유용한 상황
상황 | 적합도 |
리스트, 테이블 등 반복 요소 | ✅ 매우 적합 |
동적으로 요소가 추가/삭제되는 경우 | ✅ 매우 적합 |
클릭, 입력 등 일반 이벤트 | ✅ 적합 |
요소별로 정밀한 제어가 필요한 경우 | ⚠️ 주의 필요 |
⚠️ 이벤트 위임 시 주의할 점
- event.target이 원하는 요소가 아닐 수 있으므로 필터링이 필요합니다.
- if (event.target.matches('li')) { // 원하는 요소에만 동작 }
- 중첩된 위임 구조에서는 로직이 꼬일 수 있으므로 주의해야 합니다.
🧷 마무리 정리
이벤트 위임은
✨ 자식 요소가 아닌 부모 요소에 이벤트를 등록하고,
✨ 이벤트 버블링을 통해 자식의 이벤트를 감지하는 방식입니다.
이벤트 위임은 성능 최적화와 유지보수 측면에서 매우 유리한 기법입니다. 동적인 UI를 다루는 프론트엔드 개발자라면 반드시 익혀두어야 할 필수 개념입니다.
'CS' 카테고리의 다른 글
동기? 비동기? 밥 먹고 카톡하면서 이해해보자 (0) | 2025.06.25 |
---|---|
CORS 에러가 뭔데 자꾸 막는 건데? (프록시로 뚫자!) (1) | 2025.06.25 |
클로저, 그냥 이 글 하나로 끝내자 (일급 객체 + 렉시컬 스코프 쉽게 정리) (0) | 2025.06.24 |
[혼공컴운] 컴퓨터 구조 - 4. CPU의 작동 원리 (0) | 2024.03.31 |
[혼공컴운] 컴퓨터 구조 - 3. 명령어 (0) | 2024.03.29 |