ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 이벤트 흐름 제어 , 이벤트 캡쳐링과 버블링
    javaScript 2023. 8. 26. 14:31

    시작하면서 ..

    먼저 웹 개발에서 이벤트 처리는 사용자와 상호작용하고
    웹 어플리케이션의 동작을 제어하는 핵심 요소 중 하나이다.
    HTML의 계층적 구조로 인해 이벤트가 발생한 요소에서부터 상위 요소로 연쇄적으로 이벤트가 전파가 되는데
    여기에는 이벤트 캡쳐링과 버블링이라는 두 개념이 존재한다.
    이벤트를 흐름을 제어하는 방법과 이벤트 캡쳐링 , 버블링에 대해서 알아보겠습니다.


    아래에 하나의 예시코드가 있다.

     

    위에 핸들러는 <div>에 할당이 되어있지만 ,
    <h1> 태그를 클릭해도 동작을한다.
    왜 그럴까?

     

    HTML 요소의 계층적 구조와 연쇄적 이벤트 흐름

    HTML 문서의 각 요소들은 태그 안의 태그가 위치하는 식으로 중첩된 형태로 구성되어 있다.
    이러한 계층적 구조 특징 때문에 만일 HTML 요소에 이벤트가 발생할 경우 연쇄적 이벤트 흐름이 일어나게 된다.


    이러한 현상을 이벤트 전파(Event Propagation)라 부르며, 전파 방향에 따라 버블링과 캡처링으로 구분한다.

    • 버블링(Bubbling) : 자식 요소에서 발생한 이벤트가 바깥 부모 요소로 전파 (기본값)
    • 캡쳐링(Capturing) : 자식 요소에서 발생한 이벤트가 부모 요소부터 시작하여 안쪽 자식 요소까지 도달

    이벤트 버블링 (Event Bubbling)

    이벤트 버블링이란 한 요소에 이벤트가 발생하면 이 요소에 할당된 핸들러가 동작하고,
    이어서 부모 요소의 핸들러가 동작하고 최상단의 부모 요소를 만날 때까지 반복되면서 핸들러가 동작하는 현상을 말한다.
    브라우저의 이벤트는 기본적으로 버블링 방식으로 이벤트가 전파가 되고,
    자바스크립트 addEventLisnter( ) 함수로 요소의 이벤트를 등록하면 기본적으로 버블링 전파 방식으로 이벤트가 흐르게 되어,
    만일 자식 요소에 이벤트가 발생하면 부모 요소도 버블링 통해 이벤트가 전파되어 리스너가 호출되게 된다.

    무조건적인 이벤트 버블링 차단을 주의하세요!

    event.stopPropagation()을 통한 무조건적인 버블링 차단은 예상치 못한 문제를 발생시킬 수 있을 수 있다.

    1.중첩 메뉴 상황 : 상위 메뉴의 클릭 이벤트를 버블링으로 하위 메뉴의 클릭 이벤트까지 전달하되 , 중간 단계에서 이벤트를 중단 시키는 경우가 있을 수 있다 . 이런 상황에서는 상위 메뉴의 클릭 이벤트가 동작하지 않는다.
    2. 전체 페이지 클릭 분석 : 웹 페이지 내에서 발생한 모든 클릭 이벤트를 감지하여 행동 패턴을 분석하는 시스템이 있을 경우,
    document.addEventListener('click'...)와 같은 방식으로 구현한다. 이 때 , event.stopPropagation()으로 버블링을 중단시킨 영역은 분석 시스템의 동작을 방해하게 된다.

     

    이벤트 캡쳐링 (Event Capturing)

    캡쳐링은 버블링과는 반대로 최상위 태그에서 해당 태그를 찾아 내려간다.

    캡처링은 한 요소에 이벤트가 발생되면, 그 요소의 자손 요소의 이벤트도 같이 발생되는 이벤트 전파를 말한다. 한마디로 버블링 반대라고 볼 수 있다. 실제 코드에서 자주 쓰이지는 않는다.

    캡쳐링 간단 예시

    <html>
      <body>
      
        <!-- Main Code Starts -->
        <div id="grandparent"> 
          Grand Parent
          <div id="parent">
            Parent
            <div id="child">
              Child
            </div>
          </div>
        </div>
        <!-- Main Code Ends -->
        
        <div class="output">
          <span class="output-header">Output</span>
          <button id="output-button">Clear Output</button>
          <p id="output-text"></p>
        </div>
      </body>
    </html>

    위의 HTML 코드는 계층적으로 중첩된 <div> 요소들을 가지고 있습니다.
    각 요소는
    grandparent, parent, child라는 고유한 ID를 가지고 있으며,
    이 요소들은 다음과 같은 계층 구조를 가진다.

    - grandparent
      - parent
        - child

    아래는 자바스크립트 코드이다.

    document.querySelector('#grandparent')
      .addEventListener('click', () => {
        print('Grandparent click event')
      }, true)
      
    document.querySelector('#parent')
      .addEventListener('click', () => {
        print('Parent click event')
      }, true)
      
    document.querySelector('#child')
      .addEventListener('click', () => {
        print('Child click event')
      }, true)

    위의 코드는 각 요소에 클릭 이벤트 리스너를 등록하고 있다.
    각 리스너는 해당 요소의 클릭 이벤트가 발생했을 때, 캡쳐링 단계에서 실행되도록 설정되어 있다.

    실제 이벤트가 발생했을 때 , 어떤 이벤트 리스너가 어떤 순서로 실행이 되는지 살펴보자.

    1. <div id="grandparent"> 클릭 이벤트가 발생하면 Grandparent click event가 출력

    2. <div id="parent"> 클릭 이벤트가 발생하면 Parent click event가 출력

    3. <div id="child"> 클릭 이벤트가 발생하면 Child click event가 출력됩니다.

     

    위와 같이 캡쳐링 단계에서 각 요소의 클릭 이벤트 리스너가 실행되며 , 최상위 요소부터 시작하여 실제 이벤트가 발생한 요소로 이벤트가 전파된다.

     

    이 예시 코드를 실행하고 각 요소를 클릭해보면 , 클릭 이벤트가 캡쳐링 단계에 따라 최상위 요소에서 항위 요소로 이벤트가 전파되는 것을 확인을 할 수 있다.

     

     

    마치며..

    이벤트 버블링과 캡쳐링에 대해서 알아보았다.

    예전에 코드를 작성하면서 버블링에 대해서 이미 알고 있었던 개념이긴 하지만
    이번 계기로 어떤 원리로 이렇게 동작하는지에 대해서 잘 알게 된것 같다. 

    출처:  https://ko.javascript.info/bubbling-and-capturing

    출처: https://medium.com/gammastack/event-capturing-bubbling-and-target-in-javascript-52c1453df82e

     

    'javaScript' 카테고리의 다른 글

    변수  (0) 2023.10.05
    method (forEach,map,filter,reduce)정리  (0) 2023.02.21
    비동기 프로그래밍 Ajax  (0) 2022.07.03
    딥다이브 빌트인 객체  (0) 2022.06.21
    딥다이브 let,const 키워드와 블록 레벨 스코프  (0) 2022.06.20
Designed by Tistory.