Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript 이벤트 버블링(Event Bubbling) vs 이벤트 캡처링(Event Capturing) 차이점 완벽 정리

JavaScript에서 이벤트 전파(Event Propagation)는 크게 이벤트 버블링이벤트 캡처링 두 가지 방식으로 나뉩니다. 두 개념은 DOM 트리에서 이벤트가 어떤 방향으로 전달되는지를 결정하며, 실무에서 이벤트 처리 로직을 설계할 때 반드시 이해해야 하는 핵심 개념입니다.

이벤트 버블링(Event Bubbling)이란?

이벤트 버블링은 특정 요소에서 이벤트가 발생했을 때, 해당 요소의 이벤트 핸들러가 가장 먼저 실행되고, 그다음 부모 요소로, 마지막에는 document와 같은 최상위 조상 요소까지 거품이 올라오듯 순차적으로 전파되는 방식입니다.

이벤트 캡처링(Event Capturing)이란?

이벤트 캡처링은 버블링과 정반대의 동작을 합니다. 이벤트가 최상위 부모 요소에서 시작하여 자식 요소 방향으로 아래로 내려가며 전달됩니다. 즉, 조상 → 부모 → 자식 순서로 이벤트 핸들러가 실행됩니다.

JavaScript 이벤트 버블링 vs 캡처링 코드 예제

아래 예제는 두 개의 OUTER div와 그 안에 포함된 INNER div를 사용해 버블링과 캡처링의 동작 차이를 비교합니다. addEventListener()의 세 번째 인자인 useCapture 값을 true로 설정하면 캡처링 단계에서, 생략하거나 false로 설정하면 버블링 단계에서 이벤트가 처리됩니다.

예제 코드

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
    body {
        font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
    }
    .result {
        font-size: 18px;
        font-weight: 500;
        color: blueviolet;
    }
    .outer {
        display: inline-block;
        width: 400px;
        height: 200px;
        font-size: 20px;
        background-color: chartreuse;
    }
    .inner {
        width: 200px;
        height: 100px;
        font-size: 20px;
        background-color: blueviolet;
        text-align: center;
        margin: 20px;
    }
    .tags {
        display: inline-block;
        width: 400px;
        font-weight: bold;
        font-size: 18px;
    }
</style>
</head>
<body>
<h1>Event bubbling vs event capturing</h1>
<div class="outer">
OUTER
<div class="inner">INNER</div>
</div>
<div class="outer">
OUTER
<div class="inner">INNER</div>
</div>
<br />
<div class="tags">Bubbling</div>
<div class="tags">Capturing</div>
<div class="result"></div>
<script>
    let outerDiv = document.querySelectorAll(".outer");
    let innerDiv = document.querySelectorAll(".inner");
    let resEle = document.querySelector(".result");
    outerDiv[0].addEventListener("click", () => {
        resEle.innerHTML += "Outer div has been clicked" + "<br>";
    });
    innerDiv[0].addEventListener("click", () => {
        resEle.innerHTML = "";
        resEle.innerHTML += "Inner div has been clicked" + "<br>";
    });
    outerDiv[1].addEventListener("click",() => {
        resEle.innerHTML = "";
        resEle.innerHTML += "Outer div has been clicked" + "<br>";
    },true);
    innerDiv[1].addEventListener("click",() => {
        resEle.innerHTML += "Inner div has been clicked" + "<br>";
    }, true);
</script>
</body>
</html>

실행 결과

JavaScript 이벤트 버블링(Event Bubbling) vs 이벤트 캡처링(Event Capturing) 차이점 완벽 정리

버블링 방식이 적용된 INNER div를 클릭한 경우 — INNER div의 핸들러가 먼저 실행된 뒤 OUTER div의 핸들러가 실행됩니다.

JavaScript 이벤트 버블링(Event Bubbling) vs 이벤트 캡처링(Event Capturing) 차이점 완벽 정리

캡처링 방식이 적용된 INNER div를 클릭한 경우 — OUTER div의 핸들러가 먼저 실행되고, 이후 INNER div의 핸들러가 실행됩니다.

JavaScript 이벤트 버블링(Event Bubbling) vs 이벤트 캡처링(Event Capturing) 차이점 완벽 정리

정리

기본적으로 모든 이벤트 리스너는 버블링 단계에서 동작하지만, addEventListener의 세 번째 매개변수를 true로 지정하면 캡처링 단계에서 이벤트를 받을 수 있습니다. 또한 event.stopPropagation() 메서드를 활용하면 원하는 시점에 이벤트 전파를 중단시킬 수 있으므로, 복잡한 UI 구조에서 이벤트 흐름을 제어할 때 유용하게 활용됩니다.