이벤트 전파

승민·2025년 4월 18일
0

면접 대비

목록 보기
18/31

이벤트 전파(Event Propagation)는 웹 브라우저에서 이벤트가 발생했을 때, 해당 이벤트가 DOM 트리 내에서 어떻게 전달되는지를 설명하는 개념입니다. 자바스크립트에서 이벤트 전파는 주로 캡처링(Capturing), 타겟(Target), 버블링(Bubbling)의 세 단계로 나뉘며, 이는 이벤트가 발생한 요소와 그 부모/자식 요소 간의 관계를 기반으로 동작합니다.

이벤트 전파의 세 단계

  1. 캡처링 단계 (Capturing Phase)
  • 이벤트가 DOM 트리의 최상위 요소(예: window 또는 document)에서 시작해 이벤트가 발생한 대상 요소까지 내려가는 단계.
  • 이벤트가 부모 요소에서 자식 요소로 전파됨.
  • 예: <div> 안에 <button>이 있고 버튼을 클릭하면, window → document → <html> → <body> → <table> → <tbody> -> <tr> -> <td> 순으로 이벤트가 전달.
  1. 타겟 단계 (Target Phase)
  • 이벤트가 실제로 발생한 대상 요소에 도달한 단계.
  • 이벤트 핸들러가 대상 요소에서 실행됨.
  • 예: <td> 클릭 시 버튼의 이벤트 핸들러가 실행.
  1. 버블링 단계 (Bubbling Phase)
  • 이벤트가 대상 요소에서 시작해 DOM 트리의 최상위 요소까지 올라가는 단계.
  • 자식 요소에서 부모 요소로 이벤트가 전파됨.
  • 예: <button> 클릭 후 <td> → <tr> -> <tbody> -> <table> → <body> → <html> → document → window 순으로 이벤트가 전달.
    참고: 일부 이벤트(예: focus, blur)는 버블링되지 않음.

이벤트 전파 제어

addEventListener의 세 번째 인자 설정

  • 기본값은 false (버블링 단계에서 이벤트 처리).
  • true로 설정 시 캡처링 단계에서 처리.
  • 예: element.addEventListener("click", handler, true); → 캡처링 단계에서 실행.

event.stopPropagation():

  • 이벤트 전파를 중단해 이후 단계(캡처링 또는 버블링)로 전달되지 않도록 함.
  • 예: 버튼 클릭 시 부모 <div>로 이벤트가 버블링되지 않게 막음.

정리

이벤트 전파는 DOM에서 이벤트가 발생했을 때, 이벤트가 트리 구조를 따라 전달되는 과정이고 세 단계로 나뉩니다.

  • 캡처링: 이벤트가 최상위(window)에서 대상 요소까지 내려감.
  • 타겟: 이벤트가 대상 요소에서 발생.
  • 버블링: 이벤트가 대상에서 최상위로 올라감.

addEventListener의 세 번재 인자 설정을 통해 캡처링(true) 또는 버블링(false) 단계에서 처리할 수 있으며, event.stopPropagation()으로 전파를 막을 수 있습니다. 실무에서는 이벤트 위임으로 성능을 최적화합니다.

이벤트 위임
부모 요소에 단일 이벤트 핸들러를 등록해 자식 요소의 이벤트를 처리해 메모리 사용량을 줄이고 성능을 최적화합니다.
예: 동적 리스트(<li>)에서 각 <li>에 핸들러를 추가하는 대신, 부모 <ul>에 핸들러를 등록.

캡처링과 버블링의 실제 사용 사례
캡처링은 이벤트가 하위 요소로 전파되기 전에 부모에서 먼저 처리할 때 유용합니다(예: 전역 클릭 추적). 버블링은 이벤트 위임에 주로 사용되며, 동적 요소의 이벤트를 부모에서 처리해 메모리를 절약합니다.

버블링되지 않는 이벤트
focus, blur, mouseenter, mouseleave 같은 이벤트는 버블링되지 않습니다. 대신, 캡처링 단계에서 처리하거나, focusin, focusout처럼 버블링되는 대체 이벤트를 사용할 수 있습니다. 버블링 여부는 이벤트 사양에 따라 다르며, MDN에서 확인할 수 있습니다.

React에서 이벤트 전파 처리
React는 합성 이벤트를 사용해 브라우저의 네이티브 이벤트를 추상화합니다. 이벤트는 루트 요소에서 위임 방식으로 처리되며, 버블링은 기본적으로 지원하지만 캡처링은 { onClickCapture }로 설정 가능합니다.

function Component() {
  return <div onClickCapture={() => console.log("Captured")}>
    <button onClick={() => console.log("Bubbled")}>Click</button>
  </div>;
}

0개의 댓글