이벤트 캡처링 (Event capturing)

96Smilepeace·2023년 4월 16일
0

기술면접

목록 보기
2/3
post-thumbnail

🕸️ 이벤트 캡처링이란?

이벤트 버블링과는 반대되는 성질을 가지고 있으며 상위요소에서 하위요소로 이벤트가 전달되는 특성입니다.

표준 DOM 이벤트에 정의된 이벤트 흐름엔 3가지 단계가 있습니다.

1. 캡처링 단계 - 이벤트가 하위 요소로 전파되는 단계
2. 타깃 단계 - 이벤트가 실제 타깃요소로 전달되는 단계
3. 버블링 단계 - 이벤트가 상위 요소로 전파되는 단계


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

위 사진을 참고하여 <td> 를 클릭하면 이벤트가 최상위 조상에서 시작해 아래로 전파되고 (캡처링), 이벤트가 타깃 요소에 도착해 실행 (타깃 단계), 다시 위로 전파됩니다 (버블링 단계).

캡처링 HTML -> BODY -> TABLE -> TBODY -> TR -> TD
타깃 요소 TD - 이벤트가 발생
버블링 TD -> TR -> TBODY -> TABLE -> BODY -> HTML

on<event>, addEventListener(event, handler)를 이용하여 할당된 핸들러는 캡처링에 대해 전혀 알 수 없습니다. 이 핸들러들은 타깃, 버블링 단계에 대해서만 동작합니다.

그렇기에 캡처링 단계에서 이벤트를 잡아내려면 addEventListener의 capture 옵션을 true로 설정해야 합니다.

//아래 두 코드는 같은 방식으로 동작합니다.

.addEventListener(..., {capture: true});
.addEventListener(..., true);

cature 옵션은 두 가지 값을 가질 수 있습니다.
1. flase이면 (default) 핸들러는 버블링 단계에서 동작합니다.
2. true이면 핸들러는 캡처링 단계에서 동작합니다.

위 사진을 참고하여 코드를 작성해보고 캡처링과 버블링 타깃 단계에 대해 브라우저상 어떻게 동작하는지 알아보겠습니다.

    <style>
      body * {
        margin: 10px;
        border: 1px solid black;
      }
    </style>

  <body>
    <table>
      <tbody>
        <tr>
          <td onclick="evevt()">td</td>
        </tr>
      </tbody>
    </table>

    <script>
      for (let elem of document.querySelectorAll("*")) {
        elem.addEventListener(
          "click",
          (e) => alert(`캡쳐링: ${elem.tagName}`),
          true
        );
        elem.addEventListener("click", (e) => alert(`버블링: ${elem.tagName}`));
      }
      const target = document.querySelector("td");
      const event = target.addEventListener("click", (e) =>
        alert("타깃 요소 :" + e.target.tagName)
      );
    </script>
  </body>

캡처링 단계로 상위요소<HTML>에서 이벤트가 발생한 하위요소<TD>순으로 동작한 후 반대로 하위요소에서 상위요소로 올라오는 버블링 단계가 실행되며 최초 타깃요소를 같이 호출하게 되는것을 볼 수 있습니다.

현재 발생 중인 이벤트의 흐름의 단계를 알 수 있는 event.eventPhase 프로퍼티가 존재합니다. 반환되는 정수값에 따라 이벤트 흐름의 실행 단계를 구분합니다.

addEventListener(..., true)로 핸들러를 할당했다면 핸들러를 지울떄
removeEventListener(..., true)를 사용하려 지워야하 하며, 같은 단계에 있어야 핸들러가 삭제됩니다.

같은 요소와 같은 단계에 설정한 리스너는 설정 순서대로 동작합니다.
특정요소에 addEventListener를 사용하여 한 단계에 여러 이벤트 핸들러를 설정하였다면 해당 핸들러는 설정한 순서대로 동작합니다.

.addEventListener(evnet, handler1); // 첫 번쨰로 트리거 됩니다.
.addEventListener(evnet, handler2);


이벤트 캡처링 기능 참고 - JAVASCRIPT.INFO

profile
🔥 노력천재

0개의 댓글