searchgithubemail

이벤트 버블링과 이벤트 캡처링

이벤트 버블링과 이벤트 캡처링에 대한 이해

2025-05-23

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

이벤트 전파(Event Propagation)이란?

이벤트 전파는 DOM 에서 발생한 이벤트가 전달되는 과정이다. 브라우저에서는 이벤트가 발생한 요소(target element)를 기준으로 부모 요소까지 올라가거나 자식요소로 내려가면서 이벤트를 처리하는 구조를 가지고 있다. 이벤트 전파는 크게 두 가지 단계로 나눌 수 있다.


이벤트 버블링(Event Bubbling)

이벤트가 특정 DOM 요소에서 발생하면, 그 이벤트가 발생한 요소(target)에서부터 DOM 트리를 따라 상위 요소로 점점 올라가며 전파되는 과정이다. 이때 각 상위 요소에서도 이벤트가 발생한 것 처럼 처리할 수 있다.

특정 요소에서의 이벤트 발생 -> 이벤트 타겟에서부터 부모 요소로 이동 -> (부모 요소 -> 부모의 부모 -> 루트) -> 이벤트 리스너가 등록된 부모 요소들에서도 이벤트 처리 가능

<div id="parent">
    <button id="child">버튼</button>
</div>

만약 위에 버튼을 클릭한다면,

  1. 버튼에서 클릭 이벤트 발생
  2. 버튼에서 부모 요소인 div로 이벤트 전파
  3. div에서 클릭 이벤트 발생
  4. div에서 부모 요소인 body로 이벤트 전파
  5. body에서 클릭 이벤트 발생
  6. body에서 부모 요소인 html로 이벤트 전파
  7. html에서 클릭 이벤트 발생
  8. html에서 부모 요소인 document로 이벤트 전파
  9. document에서 클릭 이벤트 발생
  10. document에서 부모 요소인 window로 이벤트 전파

의 흐름으로 이벤트 버블링이 발생한다.

document.getElementById('parent').addEventListener('click', () => {
    console.log('parent 클릭됨');
});

document.getElementById('child').addEventListener('click', () => {
    console.log('child 클릭됨');
});

위와 같이 이벤트 리스너를 등록하면, 버튼을 클릭했을 때 다음과 같은 결과가 출력된다.

child 클릭됨
parent 클릭됨

버튼을 클릭했을 때, 버튼에서 발생한 클릭 이벤트가 부모 요소인 div로 전파되면서 div에서도 클릭 이벤트가 발생하게 된다. 이때, 이벤트 리스너가 등록된 순서대로 실행된다.


이벤트 캡처링(Event Capturing)

이벤트 캡처링은 이벤트 버블링과 반대 방향으로, DOM 트리의 최상위 요소에서부터 이벤트가 발생한 요소(target)까지 내려가는 과정이다.

DOM의 최상위(window 또는 document)에서 시작 -> (최상위 -> 하위 -> target 요소) -> 이벤트 타겟에 도착 후, 다시 이벤트 버블링으로 전환

  1. window에서 클릭 이벤트 발생
  2. window에서 자식 요소인 document로 이벤트 전파
  3. document에서 자식 요소인 body로 이벤트 전파
  4. body에서 자식 요소인 div로 이벤트 전파
  5. div에서 자식 요소인 button으로 이벤트 전파
  6. button에서 클릭 이벤트 발생
  7. button에서 부모 요소인 div로 이벤트 전파
  8. div에서 클릭 이벤트 발생
  9. div에서 부모 요소인 body로 이벤트 전파
  10. body에서 클릭 이벤트 발생
  11. body에서 부모 요소인 document로 이벤트 전파
  12. document에서 클릭 이벤트 발생
  13. document에서 부모 요소인 window로 이벤트 전파
  14. window에서 클릭 이벤트 발생
document.getElementById('parent').addEventListener('click', () => {
    console.log('parent 클릭됨');
}, true); // true를 추가하여 캡처링 단계에서 이벤트 리스너 등록

document.getElementById('child').addEventListener('click', () => {
    console.log('child 클릭됨');
});

위와 같이 이벤트 리스너를 등록하면, 버튼을 클릭했을 때 다음과 같은 결과가 출력된다.

parent 클릭됨
child 클릭됨

즉, 하나의 클릭이 발생하면 부모 요소에서부터 자식 요소로 내려가면서 이벤트가 발생하고, 다시 자식 요소에서 부모 요소로 올라가면서 이벤트가 발생하는 것이다. 이때, 이벤트 리스너가 등록된 순서대로 실행된다.


이벤트 버블링, 캡처링 제어

이벤트 전파 방지 (event.stopPropagation())

이벤트가 부모로 전달되는 것을 막을 수 있다.

document.getElementById('child').addEventListener('click', (event) => {
    event.stopPropagation(); // 부모 요소로 이벤트 전파 방지
    console.log('child 클릭됨');
});

기본 이벤트 방지 (event.preventDefault())

stopPropagation()와는 달리, 기본 동작(ex: 링크 클릭, 폼 제출 등)을 방지할 수 있다.

document.getElementById('link').addEventListener('click', (event) => {
    event.preventDefault(); // 기본 동작 방지
    console.log('링크 클릭됨');
});

이벤트 버블링과 캡처링 사용?

이벤트 버블링 활용

document.querySelector('ul').addEventListener('click', (e) => {
    if(e.target.tagName === 'li'){
        console.log('클릭한 항목:', e.target.innerText);
    }
});

이벤트 캡처링 활용