모자딥 40장 이벤트

릿·2023년 2월 10일
0
post-thumbnail

40. 이벤트

40.1 이벤트 드리븐 프로그래밍


  • 이벤트 핸들러 : 이벤트가 발생했을 때 호출될 함수
  • 이벤트 핸들러 등록 : 이벤트가 발생했을 때, 브라우저에게 이벤트 핸들러의 호출을 위임하는 것
  • 이벤트 드리븐 프로그래밍(event-driven programming) : 프로그램의 흐름을 이벤트 중심으로 제어하는 프로그래밍 방식

40.2 이벤트 타입


40.2.1 마우스 이벤트


40.2.2 키보드 이벤트

40.2.3 포커스 이벤트

40.2.4 폼 이벤트

40.2.5 값 변경 이벤트

40.2.6 DOM 뮤테이션 이벤트

40.2.7 뷰 이벤트

40.2.8 리소스 이벤트

40.3. 이벤트 핸들러 등록


40.3.1 이벤트 핸들러 어트리뷰트 방식

  • 이벤트 핸들러 어트리뷰트 이름은 onclick과 같이 on접두사와 이벤트 종류를 나타내는 이벤트 타입으로 이루어져 있음
...
<button onclick='sayHi('Lee')'>Click me!</button>
<script>
  function sayHi(name) {
    console.log(`Hi! ${name}.`);
  }
...
  • 이벤트 핸들러 어트리뷰트 값으로 함수 호출문 등의 문을 할당함

40.3.2 이벤트 핸들러 프로퍼티 방식

  • window객체와 Document, HTMLElement타입의 DOM객체는 이벤트에 대응하는 이벤트 핸들러 프로퍼티를 가지고 있고, 이벤트 핸들러 프로퍼티에 함수를 바인딩 하면 이벤트 핸들러가 등록됨
  • 이벤트 핸들러 프로퍼티 방식으로 이벤트 핸들러를 바인딩 하면 하나에 하나의 이벤트 핸들러만 바인딩할 수 있음
...
  const  $button = document.querySelector('button');
  
  $button.onclick = function () {
    console.log('button click');
 }
...
  • 이벤트 핸들러를 등록할 때 이벤트 타깃, 이벤트 타입, 이벤트 핸들러를 지정할 필요가 있음

40.3.3 addEventListener 메서드 방식

  • EventTarget.prototype.addEventListener메서드를 사용하여 이벤트 핸들러를 등록할 수 있음
...
  const $button = document.querySelector('button');
  
  $button.addEventListener('click', function () {
    console.log('button click');
  });
...
  • 하나 이상의 이벤트 핸들러를 바인딩할 수 있음, 하지만 참조가 동일한 이벤트 핸들러를 중복 등록하면 하나의 이벤트 핸들러만 등록됨
...
  $button.addEventListener('click', handleClick);
  $button.addEventListener('click', handleClick);
...

40.4 이벤트 핸들러 제거


  • EventTarget.prototype.removeEventListener메서드를 사용하면 addEventListener메서드로 등록한 이벤트 핸들러를 제거할 수 있음
  • 각 메서드에 전달한 인수가 일치하지 않으면 이벤트 핸들러가 제거되지 않음
...
  $button.addEventListener('click', handleClick);
  $button.removeEventListener('click', handleClick);
...
  • 무명함수를 이벤트 핸들러로 등록한 경우, 제거할 수 없음
...
  $button.addEventListener('click', () => console.log('button click));
...
  • 이벤트 핸들러 프로퍼티 방식으로 등록한 이벤트 핸들러는 이벤트 핸들러 프로퍼티에 null을 할당하면 제거할 수 있음
...
  $button.onclick = handleClick;
  $button.onclick = null;
...

40.5 이벤트 객체


  • 이벤트가 발생하면 이벤트 객체가 동적으로 생성됨
  • 생성된 이벤트 객체는 이벤트 핸들러의 첫번째 인수로 전달됨
  • 매개변수 이름은 어떤 것을 사용하여도 상관 없음
...
  function showCoords(e) {
    $msg.textContent = `clientX: ${e.clientX}, clientY: ${e.clientY}`;
  }

...
  • 이벤트 핸들러 어트리뷰트 방식의 경우, 이벤트 핸들러의 첫번째 매개변수 이름이 반드시 event여야 함
...
  <body onclick='showCoords(event)'>
...

40.5.1 이벤트 객체의 상속 구조

  • 이벤트 객체는 다음과 같은 상속 구조를 가짐
  • 이벤트 발생 시, 암묵적으로 생성되는 이벤트 객체도 생성자 함수에 의해 생성되기 때문에 프로토타입이 생성되고, 프로토타입 체인의 일원이 됨

40.5.2 이벤트 객체의 공통 프로퍼티

  • Event인터페이스의 이벤트 관련 프로퍼티는 모든 이벤트 객체가 상속받는 공통 프로퍼티
  • 이벤트 객체의 공통 프로퍼티

40.5.3 마우스 정보 취득

MouseEvent타입의 이벤트 객체 고유 프로퍼티

  • 마우스 포인트의 좌표 정보를 나타내는 프로퍼티 :
    screenX/screenY, clientX/clientY, pageX/pageY, offsetX/offsetY
  • 버튼 정보를 나타내는 프로퍼티 :
    altkey, ctrlKey, shiftKey, button

40.5.4 키보드 정보 취득

  • KeyboardEvent타입의 이벤트 객체 고유 프로퍼티
    altKey, ctrlKey, shiftKey, metaKey, key, keyCode

40.6 이벤트 전파

  • DOM트리 상에 존재하는 DOM요소 노드에서 발생한 이벤트가 이벤트 타깃을 중심으로 DOM트리를 통해 전파되는 것
  • 캡쳐링 단계(capturing phase): 이벤트가 상위 요소에서 하위 요소 방향으로 전파
  • 타깃 단계(target phase): 이벤트가 이벤트 타깃에 도달
  • 버블링 단계(bubbling phase): 이벤트가 하위 요소에서 상위 요소 방향으로 전파
  • 대부분의 이벤트는 캡처링과 버블링을 통해 전파되지만 아래 이벤트는 버블링을 통해 전파되지 않음
  1. 포커스 이벤트: focus/blur
  2. 리소스 이벤트: load/unload/abort/error
  3. 마우스 이벤트: mouseenter/mouseleave

40.7 이벤트 위임


  • 여러 개의 하위 DOM요소에 각각 이벤트 핸들러를 등록하는 대신 하나의 상위 DOM요소에 이벤트 핸들러를 등록하는 방법

40.8 DOM 요소의 기본 동작 조작


40.8.1 DOM 요소의 기본 동작 중단

  • 이벤트 객체의 preventDefault메서드는 DOM요소의 기본 동작을 중단시킴
...
  document.querySelector('a').onclick = e => {
    e.preventDefault();
  };
...

40.8.2 이벤트 전파 방지

  • 이벤트 객체의 stopPropagation메서드는 하위 DOM요소의 이벤트를 개별적으로 처리하기 위해 이벤트 전파를 중지시킴
  document.querySelector('.btn2').onclick = e => {
    e.stopPropagation();
    e.target.style.color = 'blue';
  };

40.9 이벤트 핸들러 내부의 this


40.9.1 이벤트 핸들러 어트리뷰트 방식

...
  function handleClick() {
    console.log(this); //window
  }
...
  • handleClick함수 내부의 this는 전역 객체 window를 가리킴
  • 단, 이벤트 핸들러를 호출할 때 인수로 전달한 this는 이벤트를 바인딩한 DOM요소를 가리킴
...
  <button onclick='handleClick(this)'>Click me</button>
  <script>
    function handleClick(button) {
      console.log(button); // 이벤트를 바인딩한 button요소
      console.log(this); // window
    }
...

40.9.2 이벤트 핸들러 프로퍼티 방식과 addEventListener메서드 방식

  • 이벤트 핸들러 프로퍼티 방식과 addEventListener메서드 방식 모두 이벤트 핸들러 내부의 this는 이벤트를 바인딩한 DOM요소를 가리킴
  • 화살표 함수로 정의한 이벤트 핸들러 내부의 this는 상위 스코프의 this를 가리킴

40.10 이벤트 핸들러에 인수 전달


  • 이벤트 핸들러 프로퍼티 방식과 addEventListener메서드 방식의 경우 이벤트 핸들러 내부에서 함수를 호출하면서 인수를 전달할 수 있음
...
  $input.onblur = () => {
    checkUserNameLength(MIN_USER_NAME_LENGTH);
  };
...

40.11 커스텀 이벤트


40.11.1 커스텀 이벤트 생성

  • 개발자의 의도로 생성된 이벤트를 커스텀 이벤트라고 함
// KeyboardEvent 생성자 함수로 keyup 이벤트 타입의 커스텀 이벤트 객체를 생성
const keyboardEvent = new KeyboardEvent('keyup');
console.log(keyboardEvent.type); // keyup

// CustomEvent 생성자 함수로 foo 이벤트 타입의 커스텀 이벤트 객체를 생성
const customEvent = new CustomEvent('foo');
console.log(customEvent.type); // foo
  • 생성된 커스텀 이벤트 객체는 버블링되지 않으며 preventDefault메서드로 취소할 수 없음
  • 커스텀 이벤트 객체는 이벤트 고유 프로퍼티 값을 지정할 수 없는데, 지정하려면 이벤트 생성자 함수의 두번째 인수로 프로퍼티를 전달해야 함
const keyboardEvent = new KeyboardEvent('keyup', { key: 'Enter'});

40.11.2 커스텀 이벤트 디스패치

  • 생성된 커스텀 이벤트는 dispatchEvent메서드로 이벤트를 발생시킬 수 있음
...
  $button.addEventListener('click', e => {
    console.log(e);
    alert(`${e} Clicked`);
  });
  
  const customEvent = new MouseEvent('click');
  
  // 커스텀 이벤트 디스패치(동기 처리). click 이벤트가 발생함
  $button.dispatchEvent(customEvent);
...
profile
항상 재밌는 뭔가를 찾고 있는 프론트엔드 개발자

0개의 댓글