Javascript

JS : 이벤트 버블링, 이벤트 캡처링

죽이죽이 2024. 2. 16. 12:39

이벤트 버블링이란?

※ 이벤트 버블링이란?
- 이벤트가 발생한 하위 요소에서 시작해 상위 요소로 전파되는 단계이다.
- 하위 요소를 감싸는 모든 상위 요소는 해당 이벤트를 감지할 수 있다.



※ 예시
- addEventListener의 3번째 인자로 아무값도 넣어주지 않을 경우 default 값은 버블링이다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="parent">
      <div id="first">
        <div id="second">
          <div id="third">Child</div>
        </div>
      </div>
    </div>
  </body>
  <script>
    document.getElementById("parent").addEventListener("click", (e) => {
      console.log("parent", e);
    });

    document.getElementById("first").addEventListener("click", (e) => {
      console.log("first", e);
    });

    document.getElementById("second").addEventListener("click", (e) => {
      console.log("second", e);
    });

    document.getElementById("third").addEventListener("click", (e) => {
      console.log("third", e);
    });
  </script>
</html>



※ id="third" 요소 클릭
- third 요소에서 시작해서 이벤트가 상위 요소로 전파된다. (third => second => first => parent 순서)

 

 

 

이벤트 캡처링이란?

※ 이벤트 캡처링이란?
- 이벤트가 최상위 요소에서 시작해 하위 요소로 전파되는 단계이다.


※ 예시
- addEventListener의 3번째 인자로 true 값을 넣어줄 경우 이벤트 캡처링이 일어난다.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="parent">
      <div id="first">
        <div id="second">
          <div id="third">Child</div>
        </div>
      </div>
    </div>
  </body>
  <script>
    document.getElementById("parent").addEventListener("click", (e) => {
      console.log("parent", e);
    }, true);

    document.getElementById("first").addEventListener("click", (e) => {
      console.log("first", e);
    }, true);

    document.getElementById("second").addEventListener("click", (e) => {
      console.log("second", e);
    }, true);

    document.getElementById("third").addEventListener("click", (e) => {
      console.log("third", e);
    }, true);
  </script>
</html>


※ id="third" 요소 클릭

- third 요소를 감싸고있는 최상위 요소부터 시작해서 실제 클릭 이벤트가 일어난 thrid 요소까지 이벤트가 하위로 전파된다. (parent => first => second => third 순서)


 

 

 

이벤트 위임이란?

※ 이벤트 위임이란?
- 이벤트를 하위 요소에 직접 할당하는 대신 상위 요소에 이벤트 핸들러를 할당하고, 이벤트가 버블링되어 상위 요소에 도달했을 때 필요한 처리를 수행하는 방식이다.


※ 예시
- 이벤트 버블링을 활용하여 이벤트 위임을 할 수 있다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="parent">
      <div id="child">Child</div>
    </div>
  </body>
  <script>
    document.getElementById("parent").addEventListener("click", (e) => {
      const tag = e.target.tagName;
      if (tag === "DIV") {
        alert("div " + event.target.id + " clicked!");
      }
    });
  </script>
</html>

 

 

 

이벤트 전파 방지

※ 이벤트 버블링, 이벤트 캡처링을 막는 방법
- 기존 코드
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="parent">
      <div id="child">Child</div>
    </div>
  </body>
  <script>
    document.getElementById("parent").addEventListener("click", (e) => {
      console.log("parent");
    });

    document.getElementById("child").addEventListener("click", (e) => {
      console.log("child");
    });
  </script>
</html>​


- 자식 요소를 클릭했지만 부모 요소까지 이벤트가 전파된다.


- e.stopPropagation() 사용

document.getElementById("child").addEventListener("click", (e) => {
  e.stopPropagation(); // 이벤트 전파 방지
  console.log("child");
});


- 이벤트가 전파되지 않아 자식 요소에서만 이벤트가 발생되는것을 확인할 수 있다.