프론트엔드 개발 블로그

이벤트 캡쳐링과 버블링, 이벤트 위임

by heeji_

버블링

한 요소에 이벤트가 발생하면 최상단 조상 요소를 만날 때까지 이벤트가 위로 전파되는 현상

아래 예시코드를 실행하면 1번!, 2번! alert 창이 차례로 뜬다. <button> 요소에 발생한 이벤트가 <body>까지 위로 전파된 것이다.

<body onclick="alert(`2번!`)">
  <button onclick="alert(`1번!`)">클릭해 주세요.</button>
</body>

이벤트가 전파되지 않게 막고 싶다면 stopPropagation을 활용할 수 있다.

<body onclick="alert(`버블링은 여기까지 도달하지 못합니다.`)">
  <button onclick="event.stopPropagation()">클릭해 주세요.</button>
</body>

 

캡쳐링

이벤트가 최상위 조상에서 시작해 아래로 전파되는 현상

우리가 자주 쓰는 addEventListenercapture 옵션을 줘서 캡쳐링 단계에서 이벤트를 잡아낼 수 있다. removeEventListener로 이벤트를 지울 때도 capture 옵션을 똑같이 줘야 한다.

// 캡쳐링
element.addEventListener("click", foo, true);

// 버블링 (기본값이 capture = false)
element.addEventListener("click", foo);

 

이벤트 위임

캡쳐링과 버블링을 활용해 이벤트 위임을 구현할 수 있다.

요소마다 이벤트 핸들러를 할당하지 않고 요소의 공통 조상에 이벤트 핸들러를 하나만 할당해도 여러 요소를 한꺼번에 다룰 수 있다.

아래 아이템 목록에서 <li>태그 영역을 클릭했을 때 콘솔을 찍는 코드를 만들어보자

<ul id="wrap_list">
  <li>item1</li>
  <li>item2</li>
  <li>item3</li>
  <li>item4</li>
  <li>item5</li>
</ul>

간단하게 생각해서 <li>태그에 해당하는 요소를 모두 불러오고 이를 순회하면서 이벤트 핸들러를 붙여줄 수 있다.

const $list = document.querySelectorAll("li");

$list.forEach(($li) => {
  $li.addEventListener("click", (e) => {
    console.log(e.target);
  });
});

이렇게 되면 추가 버튼을 추가하고 버튼을 클릭했을 때 wrap_list안의 <li>태그를 새로 추가할 때마다 새로 이벤트 핸들러를 붙여줘야 한다. 동적으로 이벤트를 핸들링하는 게 어려워지는 것이다.

버블링을 활용해 이벤트를 위임해보자. wrap_list 요소 (<ul> 태그)에 이벤트 핸들러를 붙이면 <li> 태그 영역이 클릭되었을 때도 같은 효과를 볼 수 있다.

$wrap_list.addEventListener("click", (e) => {
  console.log(e.target);
});

 

참고자료

'공부기록' 카테고리의 다른 글

HTML 정리  (0) 2024.03.22
SPA란?  (0) 2024.03.22
reflow와 repaint 그리고 가상돔  (0) 2024.03.22
google.com을 브라우저 주소창에 입력하면 일어나는 일  (0) 2024.03.22
critical rendering path란  (0) 2024.03.22

블로그의 정보

아자아자

heeji_

활동하기