자바스크립트에서 이벤트 흐름(Event Flow)은 세 가지 핵심 개념으로 구성됩니다.
- 이벤트 타깃(Event Target) — 이벤트가 실제로 발생한 DOM 객체를 의미합니다.
- 이벤트 버블링(Event Bubbling) — 아래에서 자세히 설명합니다.
- 이벤트 캡처링(Event Capturing) — 아래에서 자세히 설명합니다.
이벤트 버블링(Event Bubbling)이란?
이벤트 버블링은 한 요소가 다른 요소 안에 중첩되어 있고, 두 요소 모두 동일한 이벤트(예: 클릭)에 대한 리스너를 등록했을 때 이벤트 핸들러가 호출되는 순서를 말합니다. 버블링 방식에서는 이벤트가 가장 안쪽(내부) 요소에서 먼저 포착되어 처리된 후, 바깥쪽(외부) 요소로 전파됩니다. 마치 물속에서 거품이 위로 올라오듯 이벤트가 안에서 밖으로 퍼져 나간다고 이해하면 쉽습니다.
이벤트 캡처링(Event Capturing)이란?
이벤트 캡처링은 반대로, 이벤트가 가장 바깥쪽(외부) 요소에서 먼저 포착되어 안쪽(내부) 요소로 전파되는 방식입니다. 즉, 최상위 조상 요소부터 시작해 이벤트가 발생한 대상 요소까지 내려오는 흐름입니다.
그럼 두 방식의 동작을 예제를 통해 살펴보겠습니다.
예제용 HTML
아래 두 예제 모두 다음과 같은 HTML 구조를 사용합니다.
<div id='outer' style='background-color:red;display:inline-block;padding:50px;'>
Outer Div
<div id='inner' style='background-color:yellow;display:inline-block;padding:50px;'>
Inner Div
</div>
</div>1. 이벤트 버블링 예제
document.querySelector('#outer').addEventListener('click', e => {
console.log('Outer div is clicked');
}, false);
document.querySelector('#inner').addEventListener('click', e => {
console.log('Inner div is clicked');
}, false);addEventListener의 세 번째 인수가 false이면 버블링 단계에서 핸들러가 실행됩니다.
실행 결과
위 코드를 실행한 뒤 안쪽(inner) div를 클릭하면 콘솔에 다음과 같이 출력됩니다.
Inner div is clicked Outer div is clicked
안쪽 요소의 핸들러가 먼저 실행되고, 그다음 바깥쪽 요소의 핸들러가 실행되는 것을 확인할 수 있습니다. 이것이 바로 버블링입니다.
2. 이벤트 캡처링 예제
document.querySelector('#outer').addEventListener('click', e => {
console.log('Outer div is clicked');
}, true);
document.querySelector('#inner').addEventListener('click', e => {
console.log('Inner div is clicked');
}, true);세 번째 인수를 true로 설정하면 캡처링 단계에서 핸들러가 실행됩니다.
실행 결과
위 코드를 실행한 뒤 안쪽(inner) div를 클릭하면 콘솔에 다음과 같이 출력됩니다.
Outer div is clicked Inner div is clicked
이번에는 바깥쪽 요소의 핸들러가 먼저 실행되고, 그다음 안쪽 요소의 핸들러가 실행됩니다. 이것이 캡처링입니다.
정리
자바스크립트의 이벤트 흐름은 캡처링 단계 → 이벤트 타깃 → 버블링 단계 순으로 진행됩니다. 기본적으로 addEventListener는 버블링 단계(false)에서 동작하지만, 세 번째 인수를 true로 지정하면 캡처링 단계에서 핸들러를 실행할 수 있습니다. 두 개념의 차이를 정확히 이해하면 이벤트 위임(Event Delegation) 같은 고급 패턴도 훨씬 쉽게 활용할 수 있습니다.