이벤트

ursr0706·2020년 12월 18일
0

JavaScript

목록 보기
23/23
post-thumbnail

참고서적: 모던 자바스크립트 Deep Dive_이웅모 저

이벤트

돔이 다 로드되었을 때, 또는 사용자가 마우스 클릭했을 때와 같은 어떤 사건이 발생하면 브라우저는 이를 감지하여 그 사건에 대한 특정한 타입의 이벤트를 발생시킨다.
(마우스 클릭 발생 -> 브라우저가 클릭을 감지해서 클릭 이벤트를 발생시킨다.)
특정 이벤트가 발생했을 때 그에 맞는 함수가 실행되도록 할 수 있는데, 이를 통해 사용자와 웹페이지가 상호작용할 수 있다.

<용어정리>
이벤트 핸들러 : 이벤트가 발생했을 때 호출될 함수
이벤트 핸들러 등록 : 이벤트가 발생했을 때 브라우저에게 이벤트 핸들러의 호출을 위임하는 것

특정 사건(클릭이나 돔 로드 등)이 발생했다는 것은 브라우저가 감지할 수 있기 때문에 해당 이벤트에 대해 호출될 함수도 브라우저가 호출한다.
(이벤트가 언제 발생할지 모르기 때문에 프로그램상으로는 언제 함수가 호출돼야할지 알 수 없어서 브라우저에게 이벤트 핸들러의 호출을 위임하는것이다.)

    const $button = document.querySelector('button');

    // 사용자가 버튼을 클릭하면 함수를 호출하도록 요청
    $button.onclick = () => { alert('button click'); };

위의 예문을 보면,
사용자가 버튼을 클릭하면 브라우저가 클릭을 감지하여 클릭 이벤트를 발생시키고 등록된 이벤트 핸들러를 호출한다.

이벤트 타입

이벤트 타입은 이벤트의 종류를 나타내는 문자열이다.
(예를들어 click은 사용자가 마우스를 클릭했을 때 발생하는 이벤트이다.)
키보드, 마우스, HTML DOM, Window 객체 등에서 다양한 이벤트가 발생할 수 있다.
MDN의 Event reference에서 여러 이벤트 타입들을 확인할 수 있다.

이벤트 핸들러 등록

이벤트 핸들러는 대부분 이벤트를 발생시킬 이벤트 타깃에 바인딩한다.(이벤트 전파를 이용하여 그렇지 않은 경우도 있다)
이벤트가 발생했을 때 브라우저에게 이벤트 핸들러의 호출을 위임하는 3가지 방법이 있다.

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

HTML태그에 인라인방식으로 이벤트 핸들러를 등록하는 방식이다.
HTML태그에 이벤트 핸들러 어트리뷰트를 추가하고 이벤트 발생시 동작할 함수 호출문을 할당한다.

이벤트 핸들러 어트리뷰트는 'on + 이벤트 타입' 형식으로 넣고 반드시 함수 참조값이 아닌 함수 호출문을 할당한다.

 <button onclick="handleClick()">

위의 예시처럼 "handleClick()"이렇게 함수 호출문의 형태로 넣어줘야 한다.
이벤트 핸들러 어트리뷰트의 값은 사실 암묵적으로 생성될 이벤트 핸들러의 함수 몸체를 의미하는데, 이벤트 핸들러 어트리뷰트는 파싱되어 이벤트 핸들러 어트리뷰트 이름과 같은 이름의 함수를 암묵적으로 생성하고 이벤트 핸들러 어트리뷰트 이름과 동일한 이벤트 핸들러 프로퍼티에 할당한다.
따라서 onclick="handleClick()"형식으로 이벤트 핸들러 어트리뷰트를 추가하면 handleClick함수 호출 결과가 이벤트 핸들러가 되는 것이 아니고 암묵적으로 생성되어 handleClick함수를 호출하는 실행문을 포함한 onclick함수가 이벤트 핸들러로 등록이 되는 것이다.

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

이름 그대로 이벤트 핸들러를 객체의 프로퍼티에 값을 할당하듯이 등록하는 방식이다.
window 객체와 Document, HTMLElement 타입의 DOM 노드 객체는 이벤트에 대응하는 이벤트 핸들러 프로퍼티를 가지고 있다.
이벤트 핸들러 프로퍼티의 키는 이벤트 핸들러 어트리뷰트와 마찬가지로 'on + 이벤트 타입' 형식으로 이루어져있다.

<!DOCTYPE html>
<html>
  <body>
    <input type="button" value="click" id="btn" />
    <script>
      function printThis() {
        console.log(this);
      }
      
      //이벤트 핸들러 프로퍼티 방식
      document.getElementById('btn').onclick = printThis;
    </script>
  </body>
</html>

이처럼 <이벤트 타깃>.<on+이벤트 타입> = 이벤트 핸들러 의 형식으로 등록한다.
주의할 점은 이벤트 핸들러 프로퍼티에는 하나의 이벤트 핸들러만 등록할 수 있다.
객체의 프로퍼티는 프로퍼티 값을 갱신할 수 있기 때문에 같은 이벤트 핸들러 프로퍼티에 여러번 이벤트 핸들러를 등록해도 결국 재할당으로 동작되어 제일 마지막에 바인딩된 이벤트 핸들러만 등록이 된다.

addEventListener 메서드 방식

EventTarget.prototype.addEventListener 메서드를 사용하여 이벤트 핸들러를 등록할 수 있다.

이벤트 타깃.addEventListener('이벤트 타입',이벤트 핸들러[,캡쳐 사용 여부]);

첫 번째 매개변수인 이벤트 타입 문자열에는 이전의 등록방식과는 달리 on을 붙이지 않는다.
addEventListener 메서드는 하나 이상의 이벤트 핸들러를 등록할 수 있다. 이때 이벤트 핸들러는 등록된 순서대로 호출된다. 단, 참조가 동일한 이벤트 핸들러를 중복 등록하면 하나의 핸들러만 등록된다.

이벤트 핸들러 제거

addEventListener 메서드로 등록한 이벤트 핸들러를 제거하려면 EventTarget.prototype.removeEventListener 메서드를 사용한다.

$button.removeEventListener('click', handleClick);

단, addEventListener 메서드에 전달한 인수와 removeEventListener 메서드에 전달한 인수가 일치하지 않으면 이벤트 핸들러가 제거되지 않는다.

$button.onclick = null;

이벤트 핸들러 프로퍼티 방식으로 등록한 이벤트 핸들러는 removeEventListener 메서드로 제거할 수 없다. 이벤트 핸들러 어트리뷰트 또는 이벤트 핸들러 프로퍼티 방식으로 등록한 이벤트 핸들러를 제거하려면 이벤트 핸들러 프로퍼티에 null을 할당한다.

이벤트 객체

이벤트가 발생하면 이벤트 객체가 생성되어 이벤트 핸들러의 첫 번째 인수로 전달된다.
이 때 이벤트 객체는 해당 이벤트에 관한 다양한 정보가 담겨있다.
이벤트 객체를 전달받으려면 이벤트 핸들러를 정의할 때 객체를 전달받을 매개변수를 명시적으로 선언해야하며 이름은 자유롭게 쓸 수 있다.(보통 e라고 쓴다)
그러나 이벤트 핸들러 어트리뷰트 방식으로 등록했다면 반드시 호출문의 인자로 'event'를 넣어줘야 한다.(어트리뷰트값을 몸체에 포함한 암묵적으로 생성된 이벤트 핸들러의 첫 매개변수의 이름이 event로 정해져있기 때문이다)
event가 아닌 다른 이름의 매개변수를 쓰면 이벤트 객체를 전달받지 못한다.

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

모든 이벤트 객체가 상속받는 공통적인 프로퍼티가 있다.

  • type: 이벤트 타입
  • target: 이벤트를 발생시킨 DOM요소
  • currentTarget: 이벤트 핸들러가 바인딩된 DOM 요소
  • eventPhase: 이벤트 전파 단계
    - 0: 이벤트 없음, 1: 캡처링 단계, 2: 타깃 단계, 3: 버블링 단계
  • bubbles: 이벤트를 버블링으로 전파하는지 여부
  • cancelable: preventDefault 메서드를 호출하여 이벤트의 기본 동작을 취소할 수 있는지 여부
  • defaultPrevented: preventDefault 메서드를 호출하여 이벤트를 취소했는지 여부
  • isTrusted: 사용자의 행위에 의해 발생한 이벤트인지 여부
  • timeStamp: 이벤트가 발생한 시각(1970/01/01/00:00:00부터 경과한 밀리초)
profile
멋진 둥지를 위한 제비의 흔적

0개의 댓글