TIL22. 이벤트 버블링, 캡쳐링과 델리게이션

imloopy·2022년 4월 26일
1

Today I Learned

목록 보기
22/56
post-custom-banner

이벤트가 전달되는 과정

이벤트가 전달되는 과정은 크게 세 과정으로 나눌 수 있다.

  1. 캡쳐링 단계
    1. window 객체에서 타깃을 찾아가기 위해 대상 객체까지 이벤트가 전파되는 단계를 뜻한다.
  2. 타깃 단계
    1. 이벤트가 타깃에 전파되는 단계이다.
    2. 만약 이벤트 타깃에 핸들러를 등록했다면, 이 시점에 핸들러가 실행되게 된다.
  3. 버블링 단계
    1. 타깃으로부터 이벤트가 부모로 전파되어 이벤트가 window 객체로 전달되는 단계를 뜻한다.
<!DOCTYPE HTML>
<html>
  <head>
    <style>
      .div1 {
        width: 300px;
        height: 300px;
        background-color: black;
      }
      
      .div2 {
        width: 200px;
        height: 200px;
        background-color: red;
      }
      
      .div3 {
        width: 100px;
        height: 100px;
        background-color: green;
      }
    </style>
  </head>
  </head>
  <body>
    <div id="div1" class="div1">
      <div id="div2" class="div2">
        <div id="div3" class="div3">
        </div>
      </div>
    </div>
  <script>
    document.getElementById('div1', (e) => {
      console.log('div1 click')
    })
    document.getElementById('div2', (e) => {
      console.log('div2 click')
    })
    document.getElementById('div3', (e) => {
      console.log('div3 click')
    })
  </script>
  </body>
</html>

여기서 div3를 클릭했을 때를 가정하고 이벤트의 전파 과정을 살펴보자. div3는 중첩된 div중 가장 안쪽 구조이다.

먼저 window 객체를 통해 자식으로 이벤트가 전달된다. 이러한 이벤트 캡쳐링 과정을 통해 target에 이벤트가 전파되면, 타깃에 등록한 (여기서는 div3) 핸들러가 실행이되고, div3 click이 먼저 출력된다.

그 다음 버블링 과정을 통해 div2로 전파가 되고, 이때 div2에 등록한 핸들러가 실행된다. 마지막으로 같은 과정을 통해 div1에 등록한 핸들러가 실행되어 최종적으로 div3 → div2 → div1 순서로 출력이 될 것이다.

만약 div3가 아닌 div2, div1을 클릭했다면, 하위 컴포넌트에 등록한 메서드는 실행되지 않을 것이다.

만약 출력되는 순서를 바꾸고 싶다면 어떻게 해야할까?

div3를 클릭했더라도 상위 컴포넌트의 핸들러 먼저 실행되게 하고 싶다면, useCapture = true 옵션을 주면 된다. 이는 캡처링 과정에서 전파되는 이벤트를 캐치하여 핸들러를 실행할 수 있게 해준다.

이벤트 delegation 패턴

이벤트 델리게이션 패턴은, 이벤트 버블링이 일어나는 특성을 이용하여 현재 컴포넌트보다 상위 컴포넌트에 이벤트 핸들러를 걸어두고 상위 요소에서 하위 요소의 이벤트를 제어하는 패턴을 말한다.

이벤트 버블링에 의하여 하위 컴포넌트를 클릭하면 상위 컴포넌트로 이벤트가 전파되고 핸들러를 등록하여 이를 감지할 수 있다.

e.target, e.currentTarget의 차이?

  • e.target: 실제 이벤트가 발생한 객체
  • e.currentTarget: 실제 이벤트가 발생한 객체가 아닌, 사용자가 핸들러를 등록한 객체

이벤트 델리게이션 패턴을 사용하는 이유

이벤트 위임은 특히 리스트에 이벤트를 등록할 때 유용하다. 만약 리스트 각 요소에 이벤트를 등록한다면, 100개의 리스트 요소가 있을 때 100개의 이벤트 리스너가 존재하게 되고 이는 퍼포먼스에 부정적인 영향을 준다. 만약 상위 컴포넌트에 이벤트를 등록하고 이벤트 버블링을 통해 핸들러를 실행하게 된다면, 하나의 이벤트 리스너만으로 하위 컴포넌트의 이벤트를 모두 제어할 수 있기 때문에 자주 사용한다.

왜 이런식으로 전파가 될까?

정답이 나와있지 않아 개인적으로 생각해보았는데, DOM Tree는 트리 구조로 되어있다. 우리가 트리 자료구조를 탐색할 때, 항상 루트 노드에서 시작하여 자식 노드를 탐색하는 과정을 거친다. 이러한 트리 탐색 과정이 DOM Tree의 이벤트 전파 과정에서도 동일하게 이루어지는 듯 하다.

출처

https://yeoulcoding.me/142

post-custom-banner

0개의 댓글