이벤트 버블링(Event Bubbling)은 웹 개발에서 발생하는 이벤트 처리 방식 중 하나로, 하위 요소에서 발생한 이벤트가 상위 요소로 전파되는 현상을 나타낸다. 이벤트 버블링은 DOM 트리 구조와 관련이 있으며, 이해하기 위해서는 이벤트의 전파 과정을 알아보아야 한다.
웹 페이지의 DOM은 요소들이 중첩된 계층 구조로 이루어져 있다. 이벤트 버블링은 하위 요소에서 이벤트가 발생하면, 해당 이벤트가 해당 요소를 포함한 모든 상위 요소로 전파되는 과정을 의미한다. 이 과정에서 각 요소의 이벤트 핸들러가 순차적으로 실행된다.
예를 들어, 다음과 같은 HTML 구조가 있다고 가정해보자.
<div id="parent">
<button id="child">Click me</button>
</div>
만약 Click me
버튼을 클릭했을 때 이벤트 버블링이 발생한다면, 다음과 같은 순서로 이벤트 핸들러가 실행된다.
Click me
버튼에서 클릭 이벤트 발생.
Click me
버튼의 이벤트 핸들러 실행.
부모 div
요소의 이벤트 핸들러 실행(div
는 버튼을 포함하는 상위 요소).
더 상위 요소로 이벤트 전파, 이전 단계 반복.
최상위 document
요소까지 이벤트 전파, 이전 단계 반복.
이러한 이벤트 버블링은 이벤트의 전파 경로 상의 모든 요소들에 대한 이벤트 핸들러를 실행할 수 있게 해준다. 하지만 때로는 이벤트 버블링이 의도하지 않은 동작을 일으킬 수도 있다. 이런 경우에는 이벤트 객체의 stopPropagation()
메서드를 호출하여 이벤트의 전파를 중단할 수 있다.
좀 더 이해하기 쉬운 예시를 보자.
<body>
<div class="DIV1">
DIV1
<div class="DIV2">
DIV2
<div class="DIV3">DIV3</div>
</div>
</div>
</body>
const divs = document.querySelectorAll("div");
const clickEvent = (e) => {
console.log(e.currentTarget.className);
};
divs.forEach((div) => {
div.addEventListener("click", clickEvent);
});
div를 클릭하면 해당하는 클래스명이 콘솔에 출력되는 코드다. 자바스크립트는 기본적으로 버블링이 발생하기 때문에 DIV3
을 클릭한다면 콘솔에는 DIV3, DIV2, DIV1이 순서대로 출력된다.
이벤트 버블링은 이벤트 처리 및 이벤트 위임에 활용될 수 있으며, 웹 개발에서 중요한 개념 중 하나다.
이벤트 캡처링(Event Capturing)은 이벤트 처리 방식 중 하나로, 이벤트가 상위 요소에서 하위 요소로 향하는 과정을 의미한다. 이벤트 캡처링은 이벤트 버블링과는 반대 방향으로 이벤트가 전파되는 개념이다.
이벤트 캡처링에서 이벤트가 전파되는 순서는 이벤트 버블링과 반대로 진행된다. 캡처링 단계에서 이벤트는 최상위 요소(document)에서부터 시작하여 해당 요소의 하위 요소까지 전파된다.
이벤트 캡처링과 이벤트 버블링은 다음과 같은 단계로 이루어진다.
캡처링 단계(Capturing Phase): 이벤트가 최상위 요소(document)에서 시작하여 해당 이벤트를 포함한 상위 요소로 전파된다.
타겟 단계(Target Phase): 이벤트가 실제 대상 요소에서 발생한다.
버블링 단계(Bubbling Phase): 이벤트가 대상 요소에서 시작하여 상위 요소로 전파된다.
예를 들어, 다음과 같은 HTML 구조가 있다고 가정해보자.
<div id="parent">
<button id="child">Click me</button>
</div>
만약 Click me
버튼을 클릭했을 때 이벤트 캡처링이 발생한다면, 다음과 같은 순서로 이벤트 핸들러가 실행된다.
최상위 document
요소에서 캡처링 단계 시작.
부모 div
요소의 이벤트 핸들러 실행.
Click me
버튼의 이벤트 핸들러 실행.
더 상위의 요소로 이벤트 전파, 이전 단계 반복.
더 이해하기 쉬운 예시를 들어보자.
const divs = document.querySelectorAll("div");
const clickEvent = (e) => {
console.log(e.currentTarget.className);
};
divs.forEach((div) => {
div.addEventListener("click", clickEvent, { capture: true });
});
addEventListener
의 옵션 객체에 { capture: true }
또는 true
를 설정해주면 캡처링을 구현할 수 있다.
DIV3
를 클릭한다면 위에서부터 찾아 내려오기 때문에 콘솔에는 DIV1, DIV2, DIV3이 순서대로 출력된다.
이벤트 캡처링은 일반적으로 덜 사용되는 방식이지만, 이벤트 전파의 전체 과정을 이해하는 데 도움이 된다. 브라우저에서 이벤트가 어떻게 전파되는지 이해하면, 이벤트 캡처링과 이벤트 버블링을 조합하여 원하는 이벤트 처리 동작을 구현할 수 있다.