ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TIL-2024.03.19 - JS - 이벤트 버블링 & 캡처링
    > 기초/Javascript 2024. 3. 19. 20:57

     

     

     

    목표: 

    1. 이벤트 캡처링
    2. 이벤트 버블링 
    3. 이벤트 캡처링과 버블링 막는 방법

     

    이벤트 캡처링(Event Capturing):

    • 캡처링은 이벤트가 DOM 트리의 상위 요소에서 하위 요소로 향하는 단계 (상위 > 하위)
    • 이벤트가 발생한 요소의 부모 요소부터 시작하여 해당 요소의 가장 최상위 요소인 document까지 이벤트가 전파.
    • 예를 들어, 버튼 요소를 클릭하면, 이 클릭 이벤트는 가장 상위 요소인 document까지 전파되는데, 이 단계에서 이벤트는 이벤트 리스너에 의해 캡처링 단계에서 포착될 수 있습니다.
    // index.html
    <div id="outer">
        <div id="inner">
            <button id="button">Click me</button>
        </div>
    </div>
    
    // main.js
    document.getElementById('outer').addEventListener('click', function(){
        console.log('캡처링 단계: Outer div');
    }, true);
    
    document.getElementById('inner').addEventListener('click', function(){
        console.log('캡처링 단계: Inner div');
    }, true);
    
    document.getElementById('button').addEventListener('click', function(){
        console.log('캡처링 단계: Button');
    }, true);
    
    
    // 캡처링 단계: Outer div
    // 캡처링 단계: Inner div
    // 캡처링 단계: Button

     

     

     

    이벤트 버블링(Event Bubbling):

    • 버블링은 이벤트가 발생한 요소에서 상위 요소로 향하는 단계. (하위 > 상위) 
    • 캡처링과 반대로, 이벤트가 가장 하위 요소에서 시작하여 부모 요소로 이동.
    • 캡처링 단계 이후에 발생하며, 이벤트가 발생한 요소를 포함한 모든 부모 요소까지 이벤트가 전파.

     

    // index.html
    <div id="outer">
        <div id="inner">
            <button id="button">Click me</button>
        </div>
    </div>
    
    // main.js
    document.getElementById('outer').addEventListener('click', function(){
        console.log('캡처링 단계: Outer div');
    }, true);
    
    document.getElementById('inner').addEventListener('click', function(){
        console.log('캡처링 단계: Inner div');
    }, true);
    
    document.getElementById('button').addEventListener('click', function(){
        console.log('캡처링 단계: Button');
    }, true);
    
    document.getElementById('outer').addEventListener('click', function(){
        console.log('버블링 단계: Outer div');
    });
    
    document.getElementById('inner').addEventListener('click', function(){
        console.log('버블링 단계: Inner div');
    });
    
    document.getElementById('button').addEventListener('click', function(){
        console.log('버블링 단계: Button');
    });
    
    
    캡처링 단계: Outer div
    캡처링 단계: Inner div
    캡처링 단계: Button
    버블링 단계: Button
    버블링 단계: Inner div
    버블링 단계: Outer div

     

     

     

     

    이벤트 캡처링과 버블링 막는 방법:

     

     

     

    1. preventDefault() 메서드 사용 > 기본 동작을 취소하는 데 사용

    ... 중략 ...
      <body>
        <div>
          <a href="https://naver.com" id="naver-link">네이버</a>
        </div>
      </body>
      <script>
        document.querySelector("#naver-link").addEventListener("click", (e) => {
          e.preventDefault(); 
          console.log("preventDefault로 네이버로 이동안하고 console 만 찍어줌!")
        });
      </script>
      
      ... 중략 ...

     

     

     

     

    2. stopPropagation() 메서드 사용 > 상위 요소가 이벤트를 감지할 수 없고 이벤트리스너가 가르키고 있는 요소만 이벤트를 감지

    ... 중략 ...
    
      <body>
        <div class="div-container">
          <div class="div-button" style="cursor: pointer">날 눌러보소</div>
        </div>
      </body>
      <script>
        document.querySelector(".div-button").addEventListener("click", (e) => {
          alert(".div-button 클릭!");
        });
    
        document.querySelector(".div-container").addEventListener("click", (e) => {
          alert("body 클릭!");
        });
      </script>
      
      ... 중략 ...

     

    1. 위의 예제에서 .div-container .div-button 에 각각 click 이벤트 리스너를 할당

    2. 날 눌러보소 라는 div tag 클릭한 경우, 아래의 두장의 사진과 같이 이벤트 버블링이 발생해서 두개의 alert 문 실행

     

     

    3. 아래의 코드와 같이 e.stopPropagation() 을 사용하면, 해당 요소의 이벤트만 감지

     

        document.querySelector(".div-button").addEventListener("click", (e) => {
          e.stopPropagation();
          alert(".div-button 클릭!");
        });
    
        document.querySelector(".div-container").addEventListener("click", (e) => {
          e.stopPropagation();
          alert("body 클릭!");
        });

     

     

     

    3. 캡처링에서만 막기:

    document.getElementById('button').addEventListener('click', function(event){
        event.stopPropagation(); // 버블링을 막음
    }, true);
    
    
    // addEventListener의 세 번째 매개변수를 true로 설정하여 이벤트 캡처링 단계에서만 동작하도록 만들고, 그 안에서 stopPropagation()을 호출합니다.

    댓글

Designed by Tistory.