티스토리 뷰

자바스크립트로 사용자 인터랙션을 구현할 때 가장 흔히 마주하는 문제 중 하나는 “클릭했는데 왜 부모 요소까지 이벤트가 실행되지?” 또는 “원치 않는 이벤트가 여러 번 실행돼 버그가 생겨”라는 질문임. 특히 복잡한 DOM 구조를 가진 SPA나 리액티브 UI 개발 환경에서는 특정 요소에서 발생한 이벤트가 상위 요소로 전파되는 이벤트 버블링(Event Bubbling) 때문에 의도하지 않은 로직이 실행되어 애플리케이션 동작이 깨지거나 유지보수가 어려워짐. 이러한 문제는 초급에서 중급 개발자에게 특히 큰 혼란을 유발함.

 

예를 들어 버튼 클릭만 처리하고 싶었음에도 상위 나 의 click 핸들러가 추가로 실행돼 사용자 인터페이스가 예기치 않게 변하거나, 포커스 이벤트가 여러 번 트리거되어 성능 저하로 이어지는 사례가 있음. 이런 현상은 DOM 이벤트 전파 메커니즘을 이해하지 못했을 때 더욱 악화됨.

 

 

이벤트 버블링의 기술적 메커니즘

웹 브라우저에서 DOM(Document Object Model)은 트리 구조로 구성되어 있음. 어떤 요소에 이벤트가 발생하면, 브라우저는 이 이벤트를 DOM 트리를 따라 처리하는데, 이 과정이 이벤트 전파(Event Propagation)임. 이 전파는 크게 세 단계로 나뉘는데, 그 중 기본적으로 작동하는 것이 바로 버블링(Bubbling)임. 이벤트는 가장 안쪽(타깃) 요소에서 시작해 그 요소를 둘러싼 부모 요소들을 거슬러 올라가며 실행됨. 이런 메커니즘은 마치 물속의 거품이 아래에서 위로 떠오르는 것과 유사함.

 

버블링은 기본적으로 대부분의 UI 이벤트(예: click, mouseover, keydown)에서 활성화되며, 각 요소에 같은 이벤트 타입의 리스너가 있다면 다음 순서로 실행됨:

 

  • 1) 이벤트가 발생한 타깃 요소
  • 2) 해당 타깃의 직계 부모 요소
  • 3) 부모의 부모 요소 → … → document 또는 window까지

이 흐름을 이해하지 못하면 의도하지 않은 코드가 실행되거나, 특정 요소에만 이벤트를 처리하길 원했음에도 상위 요소까지 영향이 미치는 버그를 초래하기 쉽다.

 

 

버블링 제어와 이벤트 위임 전략

아래 표는 이벤트 버블링 관련 실전 문제와 제어 방법을 비교한 것이며, 각 방법의 효과는 DOM 전파 흐름(전파 여부, 중단 가능 여부, 예측성) 기준으로 정량화됨.

기법 전파 지속 예측 가능성 성능 영향 적용 예
기본 버블링 O 낮음 높음 단일 이벤트 처리
event.stopPropagation() X 중간 보통 부모로 이벤트 전파 차단
event.stopImmediatePropagation() X 높음 보통 같은 요소의 다른 핸들러 실행 차단
이벤트 위임 O 높음 낮음 동적 리스트 처리
  1. 버블링 차단: 특정 이벤트가 상위로 전파되는 것을 막으려면 다음 코드처럼 event.stopPropagation()을 사용함.
    
    element.addEventListener('click', function(event) {
      event.stopPropagation();
      // 원하는 로직
    });
        
  2. 즉각 중단: 같은 요소에 여러 개의 리스너가 있고 모두 실행을 막고 싶다면 event.stopImmediatePropagation() 사용함.
    
    element.addEventListener('click', function(event) {
      event.stopImmediatePropagation();
    });
        
  3. 이벤트 위임: 다수의 자식 요소의 이벤트를 하나의 상위 요소로 처리하려면 아래처럼 상위 요소에 리스너를 걸고 event.target으로 구분함.
    
    parent.addEventListener('click', function(event) {
      if (event.target.matches('button')) {
        // 버튼 클릭 처리
      }
    });
        

 

버블링 관련 오해와 주의사항

  • 버블링이 항상 문제는 아님: 이벤트가 많은 자식 요소에 걸려 있다면 오히려 이벤트 위임을 통해 리스너 수를 50% 이상 절감할 수 있음. 대규모 리스트 렌더링에서는 성능 개선에 직결됨.
  • 모든 이벤트가 버블링되는 것은 아님: focus나 일부 폼 이벤트는 기본적으로 버블링되지 않음. 이 경우에도 bubbles 속성을 확인해 전파 동작을 이해해야 함.
  • stopPropagation 과 과도한 사용 주의: 무차별적인 이벤트 중단은 상위 요소에서 이벤트 분석이나 공통 로직 실행을 방해할 수 있음. 필요 시 제한적으로 적용함.
  • 표준 DOM 이벤트 흐름 이해 필수: 이벤트 전파는 캡처링 → 타깃 → 버블링 순으로 진행되며, 이를 기반으로 코드를 설계하면 예측 가능한 UI 인터랙션을 보장할 수 있음.

기술적인 정답은 환경에 따라 다를 수 있으니, 제 글은 하나의 참고 사례로 삼아 여러분만의 최적의 해답을 찾으시길 응원합니다.