DOM 이벤트

  • 이벤트를 설정하는 것은 인라인 attribute 이벤트 핸들러, 속성 이벤트 핸들러, addEventListener() 메서드를 사용하여 수행될 수 있다. 이 중에서 addEventListener() 사용이 권장된다.
  • addEventListener()에서 세 번째 매개변수는 이벤트가 이벤트 흐름의 캡처 단계(true)에서 발생될지, 버블링 단계(false)에서 발생될지를 가리키는 Boolean 값이다. 요즘 브라우저에서는 해당 매개변수가 생략될 경우 기본 값이 false이다.

이벤트 흐름

  • 이벤트가 발생되면 DOM을 따라 흘러가거나 전파되면서 다른 노드와 개체들에서 동일한 이벤트를 발생시킨다.
  • 이벤트 흐름은 캡처 단계나 버블링 단계, 혹은 양쪽 모두로 발생되도록 프로그래밍할 수 있다.

이벤트 수신기 제거

이벤트 개체에서 이벤트 속성 얻기

기본적으로 이벤트에서 호출되는 핸들러나 콜백 함수에는 이벤트와 관련된 모든 정보를 갖고 있는 매개변수가 전송된다.

addEventListener() 사용 시 this 값

  • addEventListener() 메서드에 전달되는 이벤트 수신기 함수 내부에서 this 값은 이벤트가 연결된 노드나 개체에 대한 참조가 된다.
  • event.currentTarget 속성을 사용해도 this 속성이 제공하는 것과 동일하게 참조를 얻을 수 있다.

이벤트가 호출된 노드나 개체가 아닌 이벤트의 대상을 참조

  • event.target 속성은 이벤트가 발생된 노드나 개체(즉, 대상)에 대한 참조를 제공한다. 이벤트 흐름에서 이벤트의 진원지를 파악할 때 유용하다.

preventDefault()를 사용하여 기본 브라우저 이벤트 취소

  • 브라우저는 HTML 페이지를 사용자에게 보여줄 때 사전에 구성된 여러 이벤트를 제공한다. 이러한 브라우저 이벤트는 이벤트 핸들러 함수 내부에서 preventDefault() 메서드를 호출해서 막을 수 있다.
  • 그러나 preventDefault() 메서드는 이벤트가 전파(버블링, 캡처)되는 것을 중지시키지는 않는다.
  • 이벤트 수신기의 끝 부분에서 false를 반환해도 preventDefault() 메서드를 호출하는 것과 같은 결과를 갖는다.

stopPropgation()을 사용하여 이벤트 흐름을 중지

  • 이벤트 핸들러/수신기 내에서 stopPropagation()을 호출하면 캡처/버블링 이벤트 흐름 단계가 중지된다.
  • 그러나 노드나 개체에 직접 연결된 이벤트는 여전히 호출된다.

stopImmediatePropagation()을 사용하여 동일한 대상의 이벤트 흐름뿐만 아니라 다른 유사 이벤트도 중지

  • stopImmediatePropagation() 메서드를 호출하면, 이벤트 흐름 단계를 중지시키는 것뿐만 아니라, 이 메서드를 호출한 이벤트 수신기 이후에 연결되어 호출되는 이벤트 대상의 다른 유사 이벤트도 중지시킨다.
  • 그러나 stopImmediatePropagation()을 사용하더라도 기본 이벤트는 막지 않으므로, preventDefault()를 추가로 호출해야만 브라우저 기본 이벤트를 막을 수 있다.

사용자 정의 이벤트

  • document.createEvent(), initCustomEvent(), dispatchEvent()를 조합해서 사용하면 사용자 정의 이벤트를 addEventListener에 연결해서 호출할 수 있다.
<!DOCTYPE html>
<html lang="ko">
  <body>
    <div>Click me</div>
    <script>
      const divElement = document.querySelector("div");

      // 사용자 정의 이벤트 생성
      const myCustomEvent = document.createEvent("CustomEvent");

      // 사용자 정의 이벤트에 대한 이벤트 수신기 생성
      divElement.addEventListener(
        "anything",
        function (event) {
          console.log(event.detail.anythingIs);
        },
        false
      );

      // initCustomEvent 메서드를 사용하여 사용자 정의 이벤트를 상세히 설정한다.
      // initCustomEvent 매개변수는 'event, bubble?, cancelable?, event.detail로 전달될 값'이다.

      myCustomEvent.initCustomEvent("anything", true, false, {
        anythingIs: "Hello World",
      });

      // dispatchEvent를 사용하여 사용자 정의 이벤트 호출
      divElement.dispatchEvent(myCustomEvent);
    </script>
  </body>
</html>

이벤트 위임(delegate)

  • 이벤트 위임은 이벤트 흐름을 활용하여 단일 이벤트 수신기가 여러 개의 이벤트 대상을 처리할 수 있게 하는 프로그래밍 행위를 말한다.
  • 이벤트 위임의 부수 작용은 이벤트가 생성될 때 이벤트에 응답하기 위해 이벤트 대상이 DOM 내에 있을 필요가 없다는 것이다.
  • 이것이 가능한 이유는 이벤트 흐름 때문이며, 특히 그 중에서도 버블링 단계 때문이다.
<!DOCTYPE html>
<html lang="ko">
  <body>
    <table border="1">
      <tbody>
        <tr>
          <td>row 1 column 1</td>
          <td>row 1 column 2</td>
        </tr>
        <tr>
          <td>row 2 column 1</td>
          <td>row 2 column 2</td>
        </tr>
        <tr>
          <td>row 3 column 1</td>
          <td>row 3 column 2</td>
        </tr>
        <tr>
          <td>row 4 column 1</td>
          <td>row 4 column 2</td>
        </tr>
        <tr>
          <td>row 5 column 1</td>
          <td>row 5 column 2</td>
        </tr>
        <tr>
          <td>row 6 column 1</td>
          <td>row 6 column 2</td>
        </tr>
      </tbody>
    </table>
    <script>
      document
        .querySelector("table")
        .addEventListener("click", function (event) {
          if (event.target.tagName.toLowerCase() === "td") {
            console.log(event.target.textContent);
          }
        });
    </script>
  </body>
</html>

Reference

  • DOM을 깨우치다(코디 린들리 / O'REILLY)

0개의 댓글