
다음 코드를 보자.
<body>
<div>
<button>버튼</button>
</div>
</body>
버튼에 클릭 이벤트를 할당하고, 클릭되었을 때 console.log가 출력되도록 하였다.
document.querySelector('button').addEventListener('click', () => console.log('button'));
button을 클릭하면 어떤 일이 벌어질까?

// button
버튼의 클릭 이벤트가 실행되고, 콘솔에는 'button'이 출력될 것이다.
이번에는 div와 body에도 클릭 이벤트를 할당해 보았다.
document.querySelector('button').addEventListener('click', () => console.log('button'));
document.querySelector('div').addEventListener('click', () => console.log('div'));
document.querySelector('body').addEventListener('click', () => console.log('body'));
마찬가지로 button을 클릭해보자.

// button
// div
// body
button의 클릭 이벤트만 실행되는 것이 아니라, 다른 요소들의 클릭 이벤트도 모두 실행된다. 부모 엘리먼트도 같은 이벤트를 가지고 있기 때문이다. 만약 div와 body가 다른 이벤트를 가지고 있었다면, button을 클릭했을 때 button의 클릭 이벤트만 실행되었을 것이다.
그렇다면 이벤트는 어떤 순서로 실행될까?

이벤트 플로우는 세 단계로 나누어 볼 수 있다.
Capture phase: 브라우저에서 가장 가까운 요소부터 시작하여, 상위 요소에서 하위 요소 방향으로 이벤트가 실행된다.Target phase: 이벤트가 발생한 요소에서 이벤트가 실행된다.Bubble phase: 이벤트가 발생한 요소에서 가장 가까운 요소부터 시작하여, 하위 요소에서 상위 요소 방향으로 이벤트가 실행된다.이벤트의 중복 실행을 방지하기 위하여 브라우저에서는 이벤트가 발생한 요소가 아닌 이벤트가 전파되는 요소들에서는 캡처 단계와 버블 단계 중 하나만 선택하여 이벤트가 실행되도록 하고 있다. 보통 기본값으로 버블 단계에서만 실행되도록 설정되어 있다.

이벤트 플로우에서 버블 단계에서의 이벤트 전파 방식을 말한다. 즉, 이벤트가 하위 요소에서 상위 요소로 전달되는 방식이다. 보통 기본값으로 이벤트가 버블 단계에서만 실행되도록 설정되어 있다.
위 예시에서 button을 클릭했을 때 아래와 같은 순서로 콘솔이 출력된 이유도 이벤트 버블링이 발생했기 때문이다.
// button
// div
// body

이벤트 플로우에서 캡처 단계에서의 이벤트 전파 방식을 말한다. 즉, 이벤트가 상위 요소에서 하위 요소로 전달되는 방식이다.
div의 이벤트만 capture phase 때 실행되도록 설정해보자.
addEventListener() 의 마지막 인자로 true 를 전달하면 capture phase 때 해당 이벤트가 실행된다.
document.querySelector('div').addEventListener('click', () => console.log('div'), true);
버튼을 클릭하면 다음과 같은 순서로 이벤트가 실행되었음을 알 수 있다.
// div
// button
// body
왜 이런 순서로 이벤트가 실행되었는지 알아보자.

먼저 Capture Phase에서는 브라우저에서 가장 가까운 요소부터 시작하여, 상위 요소에서 하위 요소 방향으로 이벤트가 실행된다. 이때 캡처 단계에서 실행하도록 설정된 이벤트들이 순차적으로 실행되는데, 예시에서는 div의 이벤트만 캡처 단계에서 실행되도록 설정했으므로 콘솔에 div가 출력된다.
다음으로 실제로 이벤트가 발생한 target인 button의 이벤트가 실행된다. 콘솔에 button이 출력된다.
Bubble Phase에서는 이벤트가 발생한 요소에서 가장 가까운 요소부터 시작하여, 하위 요소에서 상위 요소 방향으로 이벤트가 실행된다. 버블 단계에서 실행하도록 설정된 이벤트들이 순차적으로 실행되는데, 예시에서는 body의 이벤트가 버블 단계에서 실행되도록 기본값으로 설정되어 있으므로 콘솔에 body가 출력된다.
이벤트 핸들링 패턴 중 하나로, 요소들의 공통된 상위 엘리먼트에 이벤트 핸들러를 할당하여 여러 하위 요소를 한꺼번에 다루는 방식이다. 이벤트가 하위 요소에서 상위 요소로 전파되는 이벤트 버블링을 이용한 방법이다.
<div onclick={handleOnClick}>
<button>첫번째</button>
<button>두번째</button>
<button>세번째</button>
</div>
event.stopPropagation() 을 쓸 수 없다.