[JS] 이벤트 위임 (Event delegation)

조수현·2025년 6월 29일

이번 주 수업시간 내용

이벤트 위임이란?

부모에게 이벤트를 하나 생성해 자식들에게 발생한 이벤트를 제어하는 것

  • 이벤트 위임의 원리는 버블링이다.

버블링

이벤트 전이에는 캡쳐링과 버블링이 있는데 그 중 버블링은 자식에게 발생한 이벤트가 부모에게도 전이되는 현상이다

예시 코드

<div class="box box1">
  box1
  <div class="box box2">
    box2
    <div class="box box3">box3</div>
  </div>
</div>
const boxes = document.querySelectorAll(".box");

for (const box of boxes) {
  box.addEventListener("click", (e) => {
    const element = e.currentTarget;

    console.log("이벤트 대상", element.className);
  });
}

결과 화면

box3를 클릭했을 때

  • box3만 클릭했지만 부모인 box2, box2의 부모인 box1에 순서대로 클릭 이벤트가 전이
  • 자식에게 발생한 이벤트를 부모가 알 수 있으니 이 원리를 이용해 부모가 자식들에게 발생한 이벤트 전체를 관리하는 방법으로 접근하는 게 이벤트 전이

이벤트 전이에 자세한 내용을 알고 싶다면?

target vs current target

  • current target: 이벤트가 바인딩된 대상
  • target: 이벤트가 발생한 대상

예시 코드

const box1 = document.querySelector(".box1");

// box1에 이벤트 바인딩
box1.addEventListener("click", (e) => {
  console.log("이벤트 바인딩된 대상", e.currentTarget.className);
  console.log("이벤트 발생 대상", e.target.className);
});

box3를 클릭했을 때 결과

  • 버블링으로 인해 3를 클릭해도 box1에 바인딩 된 이벤트가 발생

이벤트 위임 적용

위의 작성된 개념을 토대로 문제 상황에 이벤트 위임을 적용

 <ul class="card-list">
   <li class="card">card1</li>
   <li class="card">card2</li>
   <li class="card">card3</li>
   <li class="card">card4</li>
   <li class="card">card5</li>
   <li class="card">card6</li>
   <li class="card">card7</li>
</ul>
const cardList = document.querySelector(".card-list");
const cards = cardList.querySelectorAll(".card");

cards.forEach((card) => {
  card.addEventListener("click", (e) => { // card 갯수 만큼 이벤트 생성 중...
    const element = e.currentTarget; // 이벤트 바인딩 대상
    console.log("클릭!", element.innerText);
  });
});

문제 상황

  • 만약 카드가 몇 십개가 추가 된다면 그 만큼의 이벤트를 계속 생성
  • 이벤트가 많아져 앱 성능 저하
 <ul class="card-list">
   <li class="card">card1</li>
   <li class="card">card2</li>
   <li class="card">card3</li>
   <li class="card">card4</li>
   <li class="card">card5</li>
   <li class="card">card6</li>
   <li class="card">card7</li>
   <li class="card">card8</li>
   <li class="card">card9</li>
   <li class="card">card10</li>
   <li class="card">card11</li>
   <li class="card">card12</li>
   <li class="card">card13</li>
   <li class="card">card14</li>
   <li class="card">card15</li>
   ...
</ul>

이벤트 위임을 적용하면?

  • 부모 element에 이벤트 하나 작성
  • card가 몇 개가 생성되던 이벤트는 하나만 생성되기 때문에 앱 성능 개선

예시 코드

  const cardList = document.querySelector(".card-list");

  cardList.addEventListener("click", (e) => {
    const element = e.target;
    
    // element.matches(selector)
    // element가 selector와 일치하는 확인해 주는 메서드
    // 일치하는 지 확인한 후 아래 코드 블록 실행
    if (element.matches(".card")) { 
    	console.log("클릭 카드!", element.innerText);
    }
    
    // 조건문을 사용해 요소마다 다른 동작 실행 처리
    if (element.matches(".box")) { 
    	console.log("클릭 박스!", element.innerText);
    }
  });

결과 화면

  • 정상 동작 확인

마무리

이벤트 위임이 버블링 어쩌구에 대해 걍 그런가보다 하고 넘어갔는데 글 작성하면서 보니 아~ 버블링이 없었으면 이벤트 위임이 없었구나 라고 사고할 수 있게 되었다!

profile
프론트엔드 개발 블로그

0개의 댓글