JavaScript, jQuery

이벤트 위임(Event Delegation) – 성능 좋은 이벤트 처리 패턴

jonbeo 2025. 9. 26. 11:31
반응형

 

 

안녕하세요 😊
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. 장점

  1. 성능 개선
    • 많은 요소에도 리스너는 부모 한 개만 등록 → 메모리 절약
  2. 동적 요소 처리
    • 새로 추가된 자식 요소도 자동으로 이벤트 처리됨
  3. 코드 단순화
    • 유지보수가 쉬워짐

📍 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()로 실제 대상 판별
반응형