JavaScript [day 30]

HiWoong·2023년 2월 17일
0

JsStudy

목록 보기
30/34

대부분의 내용은 모던 자바스크립트 Deep Dive에서 공부한 내용을 정리했습니다.


40장 : 이벤트

  • 이벤트가 발생했을 때 호출될 함수를 이벤트 핸들러라 하고, 브라우저에게 이벤트 핸들러의 호출을 위임하는 것을 이벤트 핸들러 등록이라 한다.

이벤트 타입에는 여러가지가 있다.
마우스, 키보드, 포커스, 폼, 값 변경, DOM 뮤테이션, 뷰, 리소스등의 종류가 있다.
자주 쓰는 이벤트는 click, mousemove등의 마우스 이벤트와 keydown, keyup등의 키보드 이벤트를 자주 사용하게 될 것이다.

이벤트 핸들러를 등록하는 방법은 3가지다.

  • 이벤트 핸들러 어트리뷰트 방식
    이름은 onclick과 같이 on 접두사와 이벤트의 종류를 나타내는 이벤트 타입으로 이루어져 있다.
    오래된 코드에서 간혹 이 방식을 사용하나 더는 사용하지 않는 것이 좋다.
<html>
  <body>
    <button onclick="sayHi('Lee')">Click me!</button>
    <script>
      function sayHi(name) {
      	console.log(`Hi! ${name}.`);
      }
    </script>
  </body>
</html>
  • 이벤트 핸들러 프로퍼티 방식
    키는 이벤트 핸들러 어트리뷰트와 마찬가지로 onclick과 같이 on 접두사와 이벤트의 종류를 나타내는 이벤트 타입으로 이루어져 있다.
    이벤트 핸들러 프로퍼티에 함수를 바인딩하면 이벤트 핸들러가 등록된다.
<html>
  <body>
    <button>Click me!</button>
    <script>
      const $button = document.querySelector('button');
      
      $button.onclick = function() {
      	console.log('button click');
      };
      // $button : 이벤트 타깃
      // onclick : on + 이벤트 타입
      // function() ~ : 이벤트 핸들러
    </script>
  </body>
</html>
  • addEventListener 메서드 방식
<html>
  <body>
    <button>Click me!</button>
    <script>
      const $button = document.querySelector('button');
      
      // $button.onclick = function() {
      // 	console.log('button click');
      // };
      
      $button.addEventListener('click', function() {
      	console.log('button click');
      });
    </script>
  </body>
</html>

위 예제는 프로퍼티 방식을 addEventListener 방식으로 수정한 것이다.
addEventListener 방식은 마지막 매개변수에 이벤트 전파 단계를 지정할 수 있다.
[, useCapture]

addEventListener로 등록한 이벤트 핸들러를 제거하려면 EventTarget.prototype.removeEventLister를 사용하면 된다.
단, 인수가 다를 때는 제거되지 않는다.
이벤트 핸들러 프로퍼티 방식으로 등록한 이벤트 핸들러는 프로퍼티에 null을 할당해서 제거한다.

<html>
  <body>
    <button>Click me!</button>
    <script>
      const $button = document.querySelector('button');
      
      const handleClick = () => console.log('button click');
      
      // 프로퍼티 방식으로 이벤트 핸들러 등록
      $button.onclick = handleClick;
      
      // 제거할 수 없음
      $button.removeEventListener('click', handleClick);
      
      // null을 할당해 제거
      $button.onclick = null;
    </script>
  </body>
</html>

39장에서 학습했던 DOM과 마찬가지로 이벤트 객체도 상속 구조를 갖는다.
기본적으로 Object-Event 상속을 받고 그 이후에 특정 이벤트마다 다르게 갖는다.
Event.prototype에 정의되어 있는 이벤트 관련 프로퍼티는
type, target, currentTarget, eventPhase, bubbles, cancelable, defaultPrevented, isTrusted, timeStamp등이 있다.

DOM트리 상에 존재하는 DOM 요소 노드에서 발생한 이벤트는 DOM 트리를 통해 전파된다.
이벤트 타깃을 중심으로 DOM 트리를 통해 전파된다.
window => eventTarget : Capturing Phase
eventTarget : target Phase
eventTarget => window : bubbling Phase

<html>
  <style>
    html, body { height: 100%; }
  </style>
  <body>
    <p>버블링과 캡처링 이벤트<button>버튼</button></p>
    <script>
      // 버블링 단계의 이벤트 캐치
      document.body.addEventListener('click', () => {
      	console.log('Handler for body.');
      });
      
      // 캡처링 단계의 이벤트 캐치
      document.querySelector('p').addEventListener('click', () => {
      	console.log('Handler for paragraph.');
      }, true);
      
      // 버블링 단계의 이벤트 캐치
      document.querySelector('button').addEventListener('click', () => {
      	console.log('Handler for button.');
      });
      
      /* 출력 : 
      	 Handler for paragraph.
      	 Handler for button.
      	 Handler for body.
      */
    </script>
  </body>
</html>
  • 이벤트 위임
    여러 개의 하위 DOM 요소에 각각 이벤트 핸들러를 등록하는 대신 하나의 상위 DOM 요소에 이벤트 핸들러를 등록하는 방법을 말한다.

  • DOM 요소의 기본 동작 조작
    이게 흔히 사용하는 preventDefault이다.

  • 이벤트 전파 방지
    이벤트 객체의 stopPropagation 메서드는 이벤트 전파를 중지시킨다.
    즉, 자신이 발생시킨 이벤트가 전파되는 것을 중단하고 자신에게 바인딩된 이벤트 핸들러만 실행되도록 한다.

  • this
    이벤트 핸들러 어트리뷰트 방식은 window를 가리킨다.
    이벤트 핸들러 프로퍼티 방식과 addEventListener 방식은 이벤트 객체의 currentTarget 프로퍼티 즉 이벤트를 바인딩한 DOM 요소를 가리킨다.
    이와 별개로 화살표 함수는 상위 스코프의 this를 가리키고 함수 자체의 this 바인딩을 갖지 않는다.

profile
방갑습니다

0개의 댓글