본문 바로가기

CS

이벤트 위임(Event Delegation)이란? 성능과 유지보수를 동시에 잡는 방법

반응형

 

 

✨ 프론트엔드 필수 개념: 이벤트 위임과 이벤트 버블링 정리

웹에서 리스트나 버튼 같은 반복적인 요소에 이벤트를 걸어야 할 때, 매번 하나하나 이벤트 리스너를 붙이는 것은 비효율적입니다. 이럴 때 사용할 수 있는 똑똑한 방법이 바로 이벤트 위임(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를 다루는 프론트엔드 개발자라면 반드시 익혀두어야 할 필수 개념입니다.

반응형