반응형
안녕하세요 😊
JavaScript로 버튼이나 리스트 항목에 이벤트를 걸다 보면,
요소가 많아질수록 코드가 복잡해지고 성능 문제가 생기기 쉽습니다.
이럴 때 효과적으로 사용하는 기법이 바로 **이벤트 위임(Event Delegation)**입니다.
📍 1. 이벤트 위임이란?
- 개별 요소에 직접 이벤트를 붙이지 않고,
- 공통 부모 요소에 이벤트를 한 번만 등록해서
- 하위 요소들의 이벤트를 **버블링(bubbling)**으로 처리하는 방법입니다.
👉 즉, 수많은 자식 요소 대신 부모 한 곳에서 이벤트를 관리하는 방식입니다.
📍 2. 기본 예시 (비효율적인 방법)
리스트 항목마다 클릭 이벤트를 붙이면, 항목이 많을수록 비효율적입니다.
<ul id="menu">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
<script>
const items = document.querySelectorAll("#menu li");
items.forEach(item => {
item.addEventListener("click", () => {
console.log(item.textContent + " 클릭됨");
});
});
</script>
👉 항목이 1,000개라면 이벤트 리스너도 1,000개! 성능에 부담이 됩니다.
📍 3. 이벤트 위임 적용하기
<ul id="menu">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
<script>
document.getElementById("menu").addEventListener("click", (e) => {
if (e.target && e.target.nodeName === "LI") {
console.log(e.target.textContent + " 클릭됨");
}
});
</script>
- #menu에만 이벤트를 붙임
- 실제 클릭된 대상은 e.target으로 확인
- 결과적으로 리스너는 단 1개만 등록
📍 4. 장점
- 성능 개선
- 많은 요소에도 리스너는 부모 한 개만 등록 → 메모리 절약
- 동적 요소 처리
- 새로 추가된 자식 요소도 자동으로 이벤트 처리됨
- 코드 단순화
- 유지보수가 쉬워짐
📍 5. 실무 활용 예시
1. 동적 리스트 (댓글, 채팅 메시지)
document.querySelector(".chat").addEventListener("click", (e) => {
if (e.target.classList.contains("delete-btn")) {
e.target.parentElement.remove();
}
});
👉 나중에 추가된 댓글의 삭제 버튼도 자동으로 동작
2. 테이블 행 클릭 처리
document.querySelector("table").addEventListener("click", (e) => {
const row = e.target.closest("tr");
if (row) console.log("선택된 행:", row.rowIndex);
});
👉 수많은 행에도 깔끔하게 적용 가능
📍 6. 주의할 점
- 이벤트가 버블링되는 이벤트여야 위임 가능 (예: focus, blur는 안 됨 → focusin, focusout 사용)
- e.target은 자식 요소(아이콘, 버튼 등)일 수도 있으므로 closest()로 필요한 부모를 찾는 게 안전
- 이벤트가 너무 상위에 걸리면 불필요한 이벤트까지 처리할 수 있으니 범위를 적절히 제한
✅ 마무리
JavaScript 이벤트 위임은 성능과 유지보수를 동시에 잡을 수 있는 강력한 패턴입니다.
특히 동적으로 생성되는 요소가 많을 때는 반드시 고려해야 할 방법입니다.
👉 핵심 정리:
- 자식마다 리스너 달지 말고 부모에 이벤트를 위임하라
- e.target 또는 closest()로 실제 대상 판별
반응형
'JavaScript, jQuery' 카테고리의 다른 글
Promise와 async/await – 비동기 처리 쉽게 이해하기 (0) | 2025.09.21 |
---|---|
Debounce와 Throttle – 이벤트 최적화 핵심 개념 정리 (0) | 2025.09.14 |
Intl 완전 정복 – Date/Number/RelativeTime 현지화 포맷 가이드 (0) | 2025.09.05 |
Map & Set 완전 정복 – 언제, 왜, 어떻게 써야 할까요? (2) | 2025.09.01 |
localStorage & sessionStorage – 브라우저 데이터 저장 완벽 가이드 (1) | 2025.08.31 |