JS | 커스텀 이벤트 new Event, CustomEvent

|

요약

let event = new Event(type[, options]);

Event 객체를 사용하여 이벤트를 생성합니다.

  1. type : 이벤트 타입을 나타내는 문자열입니다. “click” , “my-event” 와 같은 이벤트가 올 수 있습니다.
  2. options :
    • bubbles : true 일 때 이벤트가 버블링됩니다.
      (default : false)
    • cancelable : true 일 때 브라우저 ‘기본 동작’이 실행되지 않습니다.
      (default : false)

이벤트 실행

  • dispatch : 일을 처리하다
elem.dispatchEvent(event);

이벤트를 생성했다면 반드시 실행해야 합니다.
dispatchEvent 메서드를 사용하면 됩니다.

예제

<button id="elem" onclick="alert('클릭!');">자동으로 클릭 되는 버튼</button>

<script>
  let event = new Event("click");
  elem.dispatchEvent(event);
</script>

elem 버튼에 dispatchEvent 를 설정합니다. 버튼을 클릭하지 않았지만 이벤트 핸들러가 작동됩니다.

isTrusted

event.isTrusted 로 스크립트로 만든 이벤트인지, 진짜 사용자가 만든 이벤트인지 구분할 수 있습니다.

  • true : 사용자 액션으로 만들어짐
  • false : 스크립트를 통해 생성되었음

요소에 이벤트 넣기

document.body.addEventListner("myEventName" , doSomething , false)

커스텀 이벤트는 반드시 addEventListner 를 통해 핸들링해야합니다.
bubble: true를 명시적으로 설정하지 않으면 버블링이 되지 않습니다.

특정 이벤트 사용법

W3 UI 이벤트 섹션에 명시된 클래스들을 반드시 관련 내장 클래스로 만들어야 합니다
제대로 작동되지 않을 수 있습니다.

let event = new MouseEvent("click", {
  bubbles: true,
  cancelable: true,
  clientX: 100,
  clientY: 100
});

alert(event.clientX); // 100

MouseEvent 와 같이 명시된 UI 이벤트 클래스를 호출하면 정상적으로 작동됩니다

let event = new Event("click", {
  bubbles: true, // Event 생성자에선
  cancelable: true, // bubbles와 cancelable 프로퍼티만 동작합니다.
  clientX: 100,
  clientY: 100
});

alert(event.clientX); // undefined, 알 수 없는 프로퍼티이기 때문에 무시됩니다.

명시된 기능이 있음에도 커스텀 이벤트를 만들면 에러가 발생합니다.
피하기 위해서는 event.clientX=100 와 같이 사용하면 되지만 명시된 UI 이벤트가 있다는 것을 아는 것이 좋습니다. [MouseEvent 표준 프로퍼티 링크]

명시된 UI 이벤트 클래스 리스트

  • UIEvent
  • FocusEvent
  • MouseEvent
  • WheelEvent
  • KeyboardEvent
  • 등등…

이벤트 직접 만들기

CustomEvent

new CustomEventnew Event 와 다르게 두번째 인수에 객체를 넣을 수 있습니다.
이 객체에 detail 이라는 프로퍼티를 추가해 정보를 이벤트에 전달할 수 있습니다.

<h1 id="elem">이보라님, 환영합니다!</h1>

<script>
  // 추가 정보는 이벤트와 함께 핸들러에 전달됩니다.
  elem.addEventListener("hello", function(event) {
    alert(event.detail.name);
  });

  elem.dispatchEvent(new CustomEvent("hello", {
    detail: { name: "보라" }
  }));
</script>

detail 프로퍼티엔 어떠한 데이터도 들어갈 수 있습니다.
detail 프로퍼티를 사용하는 이유는 다른 이벤트 프로퍼티와 충돌을 피하기 위해서입니다.
이름은 keydown 이나 click 과 같이 브라우저 내장 이벤트와 겹치게 지을 수 있지만 권장하지 않습니다.

네이티브 이벤트 이름과 겹치지 않게 커스텀 이벤트를 만드는것은 설계할 때 자주 쓰이는 전략입니다.

중첩 이벤트

이벤트는 대개 큐에서 처리됩니다. onclick 이벤트 처리 도중 새로운 이벤트가 발생되면
onclick 이벤트를 마친 뒤 순서대로 처리를 시킵니다.
이벤트 안에 다른 이벤트가 있을 때는 다른 이벤트가 진행되는 중에도 즉시 처리됩니다.

<button id="menu">메뉴(클릭해주세요)</button>

<script>
  menu.onclick = function() {
    alert(1);

    menu.dispatchEvent(new CustomEvent("menu-open", {
      bubbles: true
    }));

    alert(2);
  };

  // 1과 2 사이에 트리거됩니다
  document.addEventListener('menu-open', () => alert('중첩 이벤트'));
</script>

1 > 중첩 이벤트 > 2 순서로 실행됩니다.
이벤트 안에서는 동기적으로 처리되는 것을 알 수 있습니다.
비동기적으로 작업을 진행하기 위해서는 setTimeout 으로 감싸서 해결할 수 있습니다.

<button id="menu">Menu (click me)</button>

<script>
  menu.onclick = function() {
    alert(1);

    setTimeout(() => menu.dispatchEvent(new CustomEvent("menu-open", {
      bubbles: true
    })));

    alert(2);
  };

  document.addEventListener('menu-open', () => alert('중첩 이벤트'));
</script>

1 > 2 > 중첩 이벤트 순서로 진행되었습니다.
이벤트 핸들러들이 완전히 독립적으로 되었음을 알 수 있습니다.

참조

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

클릭하여 복사