CustomEvent, dispatchEvent
2022년 05월 23일
Javascript의 addEventListener가 기본으로 제공하는 100가지 정도의 이벤트리스너를 말고 이벤트를 직접 만들 수 있는 CustomEvent를 알아보자.
이전 글들에서 짤막하게 소개했었는데 나는 주로 UI Component를 만들 때 특정 시점에서 콜백 용도로 쓰고 있다.
기본 생성 구문은 이렇다.
// CustomEvent 생성
const 커스텀_변수명 = new CustomEvent('커스텀 이벤트 명', {
// options
detail: {
변수명: 원하는 값 // 지정하고자 하는 세부 정보
}, // 기본값 null
bubbles: boolean, // 이벤트 버블링 유무, 기본값: false
cancelable: boolean // 브라우저 기본동작 취소유무 true시 event.preventDefault() 기본값: false
});
이렇게 생성된 CustomEvent를 실행시킬 위치를 정하여 아래의 dispatchEvent를 넣어놔야한다.
타겟.dispatchEvent(커스텀_변수명);
그러면 이제 이벤트 리스너로 불러올 수 있다.
타겟.addEventListener('커스텀 이벤트 명', () => {
console.log(e.detail.변수명); // return: 원하는 값
});
이전 글 끝에서 썼듯이 난 실무에서 이런식으로 쓴다. (실제로는 EventHandler라는 bootstrap5 유틸리티를 가져와 썼다. 이거에 대해선 다음에 설명하겠다.)
/* 전략 */
const complete = () => {
/* ... */
const shown = new CustomEvent('modal.shown', {
detail: {
target: this._element, // this._element: [data-modal]
trigger: this._trigger, // this._trigger: [data-modal-trigger]
},
});
this._element.dispatchEvent(shown);
};
this._element.addEventListener('animationend', () => complete());
/* 후략 */
// 화면내의 script
const modal = document.querySelector('[data-modal]');
modal.addEventListener('modal.shown', function (e) {
console.log(e.detail.target, e.detail.trigger);
// e.detail.target: [data-modal];
// e.detail.trigger: [data-modal-trigger];
});
위 코드를 설명하자면 modal이 있는 페이지에서 modal.shown 이벤트 리스너를 호출하면 modal을 여는 버튼을 클릭했을 때 modal의 animationend가 끝나면 저 커스텀 이벤트가 실행된다.
이렇게 내가 원하는 시점에 콜백을 주기에 쉽게끔 CustomEvent를 사용할 수 있다.
참고로 IE에선 아래의 polyfill없이는 지원하지 않는다.
(function () {
if (typeof window.CustomEvent === 'function') return false;
function CustomEvent(event, params) {
params = params || {
bubbles: false,
cancelable: false,
detail: undefined,
};
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent(
event,
params.bubbles,
params.cancelable,
params.detail
);
return evt;
}
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
})();
난 실무에서 webpack같은 번들링을 쓰지 못하는 환경이라면 그냥 CustomEvent를 쓰고,
번들링을 쓸 수 있는 환경이라면 다음에 설명할 EventHandler를 쓴다.