메뉴 닫기

이벤트 전파와 버블링 이해하기 DOM 이벤트 흐름 완벽 가이드

이벤트 전파와 버블링 이해하기 DOM 이벤트 흐름 완벽 가이드

🖱️ 클릭 이벤트부터 위임까지 DOM 이벤트 흐름을 확실히 잡아보세요

웹 개발을 하다 보면 클릭이나 입력 같은 다양한 이벤트를 다루게 됩니다.
이때 단순히 이벤트 리스너를 등록하는 것을 넘어서, 이벤트가 어떤 경로로 전파되는지 이해하는 것이 중요합니다.
특히 DOM에서는 이벤트가 캡처링 → 타깃 → 버블링이라는 3단계를 거쳐 흐르며, 이를 올바르게 파악해야 이벤트 위임이나 성능 최적화를 제대로 할 수 있습니다.
많은 초보 개발자들이 버블링 개념을 헷갈리거나 무시하다가 불필요한 코드 중복이나 디버깅 문제를 겪곤 하죠.
오늘은 이 이벤트 전파 과정을 명확히 정리해 드리겠습니다.

이 글에서는 DOM 이벤트 전파 방식과 단계별 특징, 이벤트 버블링의 동작 원리, 그리고 실제로 자주 활용되는 이벤트 위임 기법까지 다룹니다.
자바스크립트에서 이벤트를 더 똑똑하게 처리하고 싶다면 반드시 알아야 하는 개념들이니, 천천히 읽어보시면 확실히 감이 잡히실 거예요.
특히 실무에서 마주칠 수 있는 예제와 함께 설명드리니 따라 읽기만 해도 자연스럽게 이해가 되실 겁니다.



🔗 DOM 이벤트 전파란 무엇인가?

DOM 이벤트 전파(Event Propagation)는 브라우저에서 발생한 이벤트가 어떤 순서와 경로를 거쳐 전달되는지를 설명하는 개념입니다.
이 과정을 이해하면 이벤트를 더 효율적으로 제어할 수 있으며, 특히 복잡한 UI를 다룰 때 불필요한 이벤트 중복을 줄일 수 있습니다.
DOM 이벤트 흐름은 크게 캡처링(Capturing) → 타깃(Target) → 버블링(Bubbling)이라는 3단계를 거칩니다.

처음에는 문서의 최상위 객체인 windowdocument에서 이벤트가 시작되어 점점 하위 요소로 내려가며 타깃 요소를 찾아갑니다.
그 후 타깃 요소에서 실제 이벤트 핸들러가 실행되고, 마지막에는 다시 상위 요소로 이벤트가 되돌아가면서 전파가 완료됩니다.
이처럼 이벤트는 단방향으로만 흘러가는 것이 아니라, 내려갔다가 다시 올라오는 구조를 가지고 있기 때문에 개발자는 각 단계에서 이벤트를 가로채거나 중단할 수 있습니다.

📌 이벤트 전파 단계 요약

  • ⬇️캡처링 단계 : 상위 요소에서 하위 요소로 이벤트가 내려가는 과정
  • 🎯타깃 단계 : 이벤트가 실제로 발생한 요소에서 실행되는 과정
  • ⬆️버블링 단계 : 타깃 요소에서 다시 상위 요소로 이벤트가 전파되는 과정

자바스크립트에서 이벤트 리스너를 등록할 때, addEventListener 메서드의 세 번째 매개변수로 true를 지정하면 캡처링 단계에서 이벤트를 감지할 수 있고, 생략하거나 false로 설정하면 기본적으로 버블링 단계에서 이벤트를 감지합니다.
이처럼 각 단계는 이벤트 제어 전략에 큰 영향을 미치기 때문에, 상황에 맞게 선택하는 것이 중요합니다.

🛠️ 캡처링 단계에서 일어나는 일

캡처링(Capturing) 단계는 이벤트 전파의 첫 번째 과정으로, 이벤트가 최상위 요소에서 시작해 점점 하위 요소로 내려가면서 타깃을 찾아가는 흐름을 의미합니다.
즉, window → document → html → body → … → target 순서로 이벤트가 이동합니다.
이 과정에서 특정 요소에 이벤트 리스너가 등록되어 있다면, 캡처링 단계에서도 이벤트를 감지할 수 있습니다.

기본적으로 자바스크립트의 addEventListener는 버블링 단계에서 이벤트를 감지합니다.
하지만 세 번째 매개변수를 true로 설정하면 캡처링 단계에서 이벤트를 감지하게 됩니다.
이는 이벤트를 보다 앞선 흐름에서 제어하고 싶을 때 유용하게 사용됩니다.

📌 캡처링 단계 활용 사례

예를 들어, 여러 겹의 중첩 요소에서 동일한 이벤트를 처리해야 하는 경우 캡처링 단계에서 먼저 가로채 특정 동작을 막을 수 있습니다.
또한, 보안이나 성능을 고려해 이벤트가 타깃 요소까지 도달하기 전에 제어하고자 할 때도 쓰입니다.

CODE BLOCK
// 캡처링 단계에서 이벤트 감지하기
document.querySelector(".outer").addEventListener("click", function() {
    console.log("캡처링 단계에서 감지됨");
}, true);

위 코드처럼 매개변수에 true를 지정하면, 클릭 이벤트가 실제 타깃에 도달하기 전에 상위 요소에서 이벤트를 처리할 수 있습니다.
이 방식은 드물게 사용되지만, 이벤트 전파를 정교하게 제어해야 할 때 큰 도움이 됩니다.



⚙️ 타깃 단계와 이벤트 버블링

이벤트가 최종적으로 도달하는 지점은 바로 타깃(Target) 단계입니다.
이 단계에서는 이벤트가 실제 발생한 요소에서 실행되며, 해당 요소에 직접 등록된 이벤트 핸들러가 실행됩니다.
즉, 사용자가 버튼을 클릭하면 버튼 요소 자체가 타깃이 되어 핸들러가 동작하는 것이죠.

타깃 단계 이후에는 버블링(Bubbling) 단계가 이어집니다.
버블링이란 이벤트가 타깃 요소에서 다시 상위 요소로 전달되는 과정을 말합니다.
이 덕분에 상위 컨테이너에 이벤트 리스너를 붙여두면 하위 요소들의 이벤트도 한 번에 처리할 수 있습니다.

📌 이벤트 버블링의 장점

  • 상위 요소 하나로 여러 하위 요소의 이벤트를 효율적으로 관리할 수 있습니다.
  • 동적으로 추가된 요소에도 이벤트 처리가 가능해 유연성이 높습니다.
  • 코드 중복을 줄이고 메모리 사용량을 최소화할 수 있습니다.

📌 버블링 중단하기

때로는 이벤트가 상위 요소로 전달되는 것을 막아야 할 때도 있습니다.
이 경우 event.stopPropagation()을 사용하면 버블링을 중단시킬 수 있습니다.

CODE BLOCK
// 버블링 중단 예시
document.querySelector(".button").addEventListener("click", function(event) {
    event.stopPropagation();
    console.log("버블링이 여기서 멈춥니다");
});

이처럼 이벤트 버블링은 매우 강력한 기능이지만, 필요할 때는 적절히 제어하지 않으면 예기치 못한 동작을 유발할 수도 있습니다.
따라서 상황에 맞게 적절히 활용하고 제어하는 습관이 중요합니다.

🔌 이벤트 위임 기법의 활용

이벤트 위임(Event Delegation)은 이벤트 버블링을 활용해, 다수의 하위 요소에 각각 이벤트 리스너를 붙이는 대신 상위 요소 하나에만 등록하는 기법입니다.
예를 들어 수십 개의 버튼이나 리스트 아이템이 있을 때, 각각에 핸들러를 추가하면 메모리 낭비와 성능 저하가 발생합니다.
하지만 부모 요소에 단 하나의 리스너를 등록하면 하위 요소의 이벤트를 한 번에 관리할 수 있어 훨씬 효율적입니다.

이 기법은 동적으로 요소가 추가되는 상황에서도 강력한 효과를 발휘합니다.
나중에 생성된 요소라도 부모 요소를 통해 이벤트를 감지할 수 있기 때문에, SPA(Single Page Application) 환경이나 Ajax 요청으로 데이터를 렌더링할 때 특히 유용합니다.

📌 이벤트 위임 예제

CODE BLOCK
// 이벤트 위임을 활용한 예제
document.querySelector(".list").addEventListener("click", function(event) {
    if(event.target && event.target.matches("li.item")) {
        console.log("리스트 아이템 클릭됨:", event.target.textContent);
    }
});

위 예제에서 .list라는 부모 요소에 이벤트 리스너를 등록했습니다.
사용자가 특정 li.item을 클릭하면, 이벤트 버블링을 통해 부모 요소에서 해당 이벤트를 감지하고 조건문을 통해 원하는 요소만 처리하게 됩니다.

💡 TIP: 이벤트 위임을 사용할 때는 event.target 속성을 잘 활용하는 것이 핵심입니다.
클릭된 요소가 원하는 조건에 맞는지 검사한 후 로직을 실행해야 예기치 못한 동작을 방지할 수 있습니다.

이벤트 위임은 성능 최적화와 코드 간결성을 동시에 챙길 수 있는 기법으로, 규모가 커질수록 그 효과가 커집니다.
따라서 복잡한 DOM 구조를 다루는 프론트엔드 개발자라면 반드시 익혀두어야 할 필수 개념입니다.



💡 실무에서 자주 쓰이는 이벤트 관리 패턴

실무에서는 다양한 상황에 맞게 이벤트 전파를 제어하고 관리해야 합니다.
특히 대규모 프로젝트에서는 성능 문제와 유지보수성까지 고려해야 하기 때문에, 몇 가지 대표적인 패턴이 널리 활용됩니다.
아래에서는 자주 사용되는 이벤트 관리 패턴들을 정리해 보겠습니다.

📌 이벤트 핸들러 최소화

모든 요소에 개별적으로 핸들러를 붙이는 것은 바람직하지 않습니다.
가능한 경우 상위 요소에 리스너를 등록하고, 하위 요소의 이벤트를 버블링을 통해 처리하는 것이 효율적입니다.
이렇게 하면 메모리 사용량을 줄이고, 코드 관리도 훨씬 쉬워집니다.

📌 기본 동작 제어하기

폼 제출이나 링크 클릭과 같은 일부 이벤트는 브라우저가 기본 동작을 가지고 있습니다.
이때 event.preventDefault()를 사용하면 해당 동작을 막을 수 있습니다.
예를 들어 Ajax를 활용해 데이터를 전송할 때, 폼의 기본 제출을 차단하는 경우가 대표적입니다.

📌 위임과 조건부 처리

이벤트 위임을 사용할 때는 모든 하위 요소를 무조건 처리하는 것이 아니라, 조건문을 통해 특정 요소만 동작하도록 제어하는 것이 중요합니다.
예를 들어 여러 버튼 중에서 특정 클래스나 데이터 속성을 가진 버튼만 처리하게 만들면, 코드 안정성이 크게 올라갑니다.

패턴 특징
이벤트 위임 상위 요소에서 하위 요소 이벤트를 한 번에 관리
stopPropagation() 이벤트 전파 중단으로 불필요한 실행 방지
preventDefault() 브라우저 기본 동작 제어

이처럼 이벤트 관리 패턴을 적절히 조합하면 코드의 품질과 성능이 크게 향상됩니다.
특히 유지보수가 잦은 프로젝트일수록 이러한 패턴을 습관처럼 적용하는 것이 장기적으로 큰 도움이 됩니다.

자주 묻는 질문 (FAQ)

이벤트 전파는 무조건 발생하나요?
이벤트 전파는 기본적으로 발생하지만, stopPropagation()이나 stopImmediatePropagation()을 사용하면 중단할 수 있습니다.
캡처링과 버블링 중 어느 쪽을 더 자주 쓰나요?
대부분의 경우 버블링 단계에서 이벤트를 처리합니다. 캡처링은 특별한 상황에서만 선택적으로 활용됩니다.
이벤트 위임은 언제 사용하는 것이 좋을까요?
하위 요소가 많거나 동적으로 추가될 때, 개별 요소마다 핸들러를 등록하는 대신 부모 요소 하나에서 관리하는 것이 효율적입니다.
preventDefault와 stopPropagation의 차이는 무엇인가요?
preventDefault()는 브라우저의 기본 동작을 막는 것이고, stopPropagation()은 이벤트가 상위로 전파되는 것을 막습니다.
버블링이 없으면 어떤 문제가 생길까요?
하위 요소마다 직접 핸들러를 등록해야 하므로 코드 중복과 성능 저하가 발생합니다. 이벤트 위임도 불가능해집니다.
모든 이벤트가 버블링 되나요?
일부 이벤트는 버블링되지 않습니다. 예를 들어 focusblur 이벤트는 버블링되지 않지만, focusinfocusout은 버블링됩니다.
이벤트 전파 흐름을 디버깅하려면 어떻게 하나요?
각 단계에 콘솔 로그를 출력하거나, 브라우저의 개발자 도구에서 이벤트 리스너를 확인해 추적할 수 있습니다.
addEventListener의 옵션에는 무엇이 있나요?
capture, once, passive와 같은 옵션을 설정할 수 있습니다. 예를 들어 once:true를 지정하면 이벤트가 한 번만 실행됩니다.

📌 DOM 이벤트 흐름 완전 정리

DOM 이벤트는 단순한 클릭이나 입력 반응을 넘어, 캡처링 → 타깃 → 버블링이라는 체계적인 흐름 속에서 동작합니다.
이 과정을 올바르게 이해하면 이벤트를 효율적으로 관리할 수 있고, 성능 최적화와 코드 간결성을 동시에 잡을 수 있습니다.
특히 이벤트 위임 기법은 실무에서 가장 널리 쓰이는 전략 중 하나로, 대규모 애플리케이션에서 필수적인 도구입니다.

이번 글에서 살펴본 것처럼, 이벤트 흐름을 이해하고 활용하는 방법은 생각보다 단순하지만, 그 효과는 상당히 큽니다.
버블링과 캡처링을 상황에 맞게 제어하고, 이벤트 위임으로 코드 재사용성을 높인다면 훨씬 깔끔하고 유지보수하기 좋은 프로젝트를 만들 수 있습니다.
프론트엔드 개발에 있어 이벤트 제어는 더 이상 선택이 아니라 기본 역량이므로, 반드시 익숙해지도록 연습해 두시는 것이 좋습니다.


🏷️ 관련 태그 : 이벤트버블링, 이벤트위임, DOM이벤트, 캡처링, 자바스크립트기초, 프론트엔드개발, 웹개발팁, 이벤트리스너, stopPropagation, preventDefault