[인터뷰준비] 이벤트 위임

이벤트 위임

1. 일반적인 이벤트 등록과 이벤트 위임

요소에 이벤트를 등록하는 일반적인 방법은 addEventListener를 이용하는 것이다. 그렇다면 100개 요소에 이벤트를 등록하고 싶다면 어떻게 해야할까? 일일이 연결해야 할까?

그러나...

이벤트흐름을 잘 이용하면 1개의 이벤트 리스너로 수 많은 요소의 이벤트를 처리할 수 있다.

이벤트 리스너가 div(파란영역)요소에 있고, 사용자가 div의 자식인 button을 클릭하면 어떤 일이 일어날까?

브라우저는 이벤트가 발생한 button 태그를 찾기 시작할 것이다.

이벤트 캡처링과 버블링을 통해 button 태그의 부모 요소인 div의 이벤트 리스너를 실행시킨다.

이때 event 객체에는 DOM에서 일어나는 이벤트의 정보가 들어있다. event.currentTarget은 이벤트가 등록된 요소를 가리킨다. 이는 이벤트리스너 안의 this가 참조하는 대상과 동일하다. 그리고 이벤트가 최초에 발생한 요소는 event.target에 참조된다.

2. EXAMPLE1

<html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
  </head>
  <body>
      <div>
          <button type="button">Button</button>
      </div>
      <script>
          const divEl = document.querySelector('div');
          divEl.style = "background: red";
          divEl.addEventListener('click', function(event) {
              console.log(event.currentTarget);
              console.log(event.target);
              console.log(this);
          });
      </script>
  </body>
</html>

div 클릭

순서

  • event.currentTarget
  • event.target
  • this

button 클릭

순서

  • event.currentTarget
  • event.target (이벤트가 최초에 발생한 요소는 event.target에 참조)
  • this

3. EXAMPLE2

코드설명

  1. 부모 div에만 이벤트를 추가
  2. 클릭된 요소가 버튼일 경우, li를 추가해준다
  3. li를 클릭하면 console.log가 찍히게 한다.
  4. 즉, 자식요소에 이벤트를 추가하지 않았지만 마치 이벤트가 등록된 것처럼 사용가능하다.
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div class="parent">
            <button type="button">generate tiem</button>
            <ul>
                <li>init</li>
            </ul>
        </div>
        <script>
            const parent = document.querySelector('.parent');
            parent.addEventListener('click', function(e) {
                if (e.target.tagName.toLowerCase() === 'button') {
                    const item = document.createElement('li');
                    item.innerText = 'Hello World';
                    parent.querySelector('ul').appendChild(item)
                }
                if (e.target.tagName.toLowerCase() === 'li') {
                    console.log('hit');
                }
            });
        </script>
    </body>
</html>

4. 정리

  • 이벤트를 발생시키고 싶은 요소를 이벤트 리스너가 등록된 부모 요소의 자식으로 배치한다.
  • 그러면 그 요소가 몇 개든 상관없이 이벤트를 등록할 수 있다
  • 요소가 동적으로 추가되어도 이벤트를 사용할 수 있다
  • 이렇게 이벤트 흐름을 활용하여 단일 이벤트 리스너가 여러개의 이벤트 대상을 처리할 수 있게 하는 프로그래밍이벤트 위임이라고 한다.
  • 이벤트 흐름은 특정 이벤트가 발생하였을 때, 해당 이벤트가 발생한 요소를 찾는 과정에서 만나는 모든 이벤트 리스너를 실행한다.
  • 이러한 이벤트 흐름의 특징을 이용하여 단일 이벤트 리스너가 여러개의 이벤트 대상을 처리할 수 있게 만들 수있다.

출처

코딩인터뷰를 저격한 JS스터디

좋은 웹페이지 즐겨찾기