2026-02-09

이벤트 버블링(Event Bubbling)과 캡처링(Event Capturing)

이벤트(Event)

사용자의 행동(클릭, 입력, 스크롤 등)이나 브라우저 동작에 의해 발생하는 신호

  • 예) click, keydown, submit, mouseover
  • DOM 요소 하나에서만 발생하는 것이 아니라, DOM 트리를 따라 전파(propagation)

HTML 이벤트 흐름

  • HTML 문서는 요소들이 중첩된 계층 구조(DOM 트리)로 이루어짐
    • 브라우저에서 발생하는 이벤트는 하나의 요소에서만 처리X
    • 문서 전체의 흐름 속에서 처리
  • 사용자가 클릭, 입력과 같은 동작을 하면 브라우저는
    1. 어떤 요소에서 이벤트 발생했는지 판단
    2. 해당 이벤트 DOM 구조 기준 순차적으로 처리

이 과정에서 이벤트는 DOM 구조를 따라 일정한 흐름을 가지고 처리

이 흐름을 바탕으로 이벤트 전파가 이루어짐

이벤트 전파(Event Propagation)

image.png

브라우저에서의 이벤트

  1. 캡처링 단계 (Capturing phase)
    • 이벤트가 최상위(document) → 타겟 요소로 내려옴
    • 이벤트가 하위 요소로 전파되는 단계
  2. 타겟 단계 (Target phase)
    • 이벤트가 실제로 발생한 요소
    • 이벤트가 실제 타깃 요소에 전달되는 단계
  3. 버블링 단계 (Bubbling phase)
    • 이벤트가 타겟 → 최상위(document)로 다시 올라감
    • 이벤트가 상위 요소로 전파되는 단계

이벤트 버블링 (Event Bubbling)

이벤트가 가장 안쪽 요소에서 발생한 뒤, 부모 요소 방향으로 전파되는 방식

  • 기본 동작
  • 대부분의 이벤트는 버블링을 사용
  • 이벤트 위임의 기반
<div id="parent">
  <button id="child">클릭</button>
</div>
parent.addEventListener("click", () => console.log("parent"));
child.addEventListener("click", () => console.log("child"));

// 버튼 클릭 시 출력 순서
// child
// parent

이벤트 캡처링 (Event Capturing)

이벤트가 최상위 요소에서 시작해 타겟 요소로 내려오는 방식

  • 기본값 X
  • 명시적으로 옵션을 줘야 사용
  • 특수한 제어가 필요한 경우에만 사용
parent.addEventListener(
  "click",
  () => console.log("parent"),
  true, // capture 옵션
);

⇒ 캡처링 단계에서 먼저 실행됨

addEventListener의 세 번째 인자

addEventListener(type, listener, options);
  • false (기본값) → 버블링 단계
  • true → 캡처링 단계

객체 형태:

addEventListener("click", handler, {
  capture: true,
});

event.target vs event.currentTarget

  • event.target: 실제 이벤트가 발생한 요소
  • event.currentTarget: 이벤트 리스너가 등록된 요소
parent.addEventListener("click", (e) => {
  console.log(e.target); // button
  console.log(e.currentTarget); // div
});

⇒ 이벤트 위임에서 핵심 개념

이벤트 위임(Event Delegation)

부모 요소 하나에 이벤트를 등록하고 자식 요소의 이벤트를 처리하는 방식

  • 이벤트 리스너 수 감소
  • 동적 요소 처리 가능
  • 성능 개선
ul.addEventListener("click", (e) => {
  if (e.target.tagName === "LI") {
    console.log("li 클릭");
  }
});

⇒ 버블링이 없으면 이벤트 위임도 없다

이벤트 전파 제어

이벤트 버블링과 캡처링 과정에서

  • 이벤트 중첩으로 인해 동일 이벤트가 중복 처리되는 상황
  • 캡처링 단계에서 불필요한 이벤트가 처리되는 성능 문제
  • 이벤트 위임 시 타겟 오작동 등 문제

해결 방법

  1. event.stopPropagation()

    button.addEventListener("click", (e) => {
      e.stopPropagation();
    });
    
    • 이벤트 전파 중단
    • 부모로 이벤트가 올라가지 않음
  2. event.preventDefault()

    form.addEventListener("submit", (e) => {
      e.preventDefault();
    });
    
    • 기본 동작 차단 (전파 차단 아님)
    • 전파 차단과 기본 동작 차단은 완전히 다른 개념

버블링이 없는 이벤트

모든 이벤트가 버블링을 하는 것은 아니다.

  • 예) focus , blur, mouseenter, mouseleave
  • focusin, focusout, mouseover, mouseout은 버블링을 지원

React에서는?

  • React는 Synthetic Event 시스템 사용
  • 이벤트를 최상위에서 위임 처리
  • 내부적으로 버블링 기반

⇒ 그래서 React에서 아래 개념 그대로 적용

  • e.stopPropagation()
  • e.target / e.currentTarget

정리 표

구분 캡처링 버블링
전파 방향 위 → 아래 아래 → 위
기본 동작 X O
사용 빈도 낮음 매우 높음
이벤트 위임 X O

요약

  • 이벤트는 DOM 트리를 따라 캡처링, 타겟, 버블링의 세 단계를 거쳐 전파된다.
  • 기본적으로 대부분의 이벤트는 버블링 단계에서 처리되며, 이를 활용해 이벤트 위임이 가능하다.
  • 캡처링은 상위 요소에서 이벤트를 먼저 처리해야 할 때 사용하며,
  • event.targetevent.currentTarget의 차이는 이벤트 위임에서 중요하다.
  • stopPropagation은 이벤트 전파를 막고, preventDefault는 기본 동작을 막는 역할을 한다.

참고자료

  • https://ko.javascript.info/bubbling-and-capturing
  • https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-%EB%B2%84%EB%B8%94%EB%A7%81-%EC%BA%A1%EC%B3%90%EB%A7%81
  • https://velog.io/@klloo/JavaScript-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%A0%84%ED%8C%8C

results matching ""

    No results matching ""