/**
* @file src/js/event-target.js
*/
import * as Events from './utils/events.js';
'글로벌/창'에서 창 가져오기;
/**
* `EventTarget`은 DOM `EventTarget`과 동일한 API를 가질 수 있는 클래스입니다. 그것
* 긴 함수를 감싸는 속기 함수를 추가합니다. 예:
* `on` 함수는 `addEventListener` 주변의 래퍼입니다.
*
* @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget}
* @클래스 이벤트 타겟
*/
const EventTarget = function() {};
/**
* 커스텀 DOM 이벤트.
*
* @typedef {객체} EventTarget~Event
* @see [속성]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
*/
/**
* 모든 이벤트 리스너는 다음 형식을 따라야 합니다.
*
* @callback EventTarget~EventListener
* @이 {이벤트 대상}
*
* @param {EventTarget~Event} 이벤트
* 이 함수를 트리거한 이벤트
*
* @param {객체} [해시]
* 이벤트 중에 전송된 데이터의 해시
*/
/**
* 이벤트 이름을 키로, 부울 값을 값으로 포함하는 개체입니다.
*
* > 메모: 여기에서 이벤트 이름이 true 값으로 설정된 경우 {@link EventTarget#trigger}
* 추가 기능이 있습니다. 자세한 내용은 해당 기능을 참조하십시오.
*
* @property EventTarget.prototype.allowedEvents_
* @사적인
*/
EventTarget.prototype.allowedEvents_ = {};
/**
* `EventTarget`의 인스턴스에 `이벤트 리스너`를 추가합니다. `이벤트 리스너`는
* 특정 이름의 이벤트가 발생했을 때 호출되는 함수.
*
* @param {문자열|문자열[]} 유형
* 이벤트 이름 또는 이벤트 이름의 배열.
*
* @param {EventTarget~EventListener} fn
* `EventTarget`으로 호출하는 함수
*/
EventTarget.prototype.on = 기능(유형, fn) {
// Events.on을 호출하기 전에 addEventListener 별칭을 제거합니다.
// 무한 유형 루프에 빠지지 않도록
const ael = this.addEventListener;
this.addEventListener = () => {};
Events.on(this, type, fn);
this.addEventListener = ael;
};
/**
* {@link EventTarget#on}의 별칭입니다. `EventTarget`이 모방하도록 허용
* 표준 DOM API.
*
* @기능
* @see {@link EventTarget#on}
*/
EventTarget.prototype.addEventListener = EventTarget.prototype.on;
/**
* `EventTarget` 인스턴스에서 특정 이벤트에 대한 `이벤트 리스너`를 제거합니다.
* 이렇게 하면 `이벤트 리스너`가 더 이상 호출되지 않습니다.
* 명명된 이벤트가 발생합니다.
*
* @param {문자열|문자열[]} 유형
* 이벤트 이름 또는 이벤트 이름의 배열.
*
* @param {EventTarget~EventListener} fn
* 제거하는 기능입니다.
*/
EventTarget.prototype.off = 기능(유형, fn) {
Events.off(this, type, fn);
};
/**
* {@link EventTarget#off}의 별칭. `EventTarget`이 모방하도록 허용
* 표준 DOM API.
*
* @기능
* @see {@link EventTarget#off}
*/
EventTarget.prototype.removeEventListener = EventTarget.prototype.off;
/**
* 이 함수는 한 번만 트리거되는 `이벤트 리스너`를 추가합니다. 후
* 첫 번째 트리거는 제거됩니다. 이것은 `이벤트 리스너`를 추가하는 것과 같습니다.
* {@link EventTarget#on} 자체에서 {@link EventTarget#off}를 호출하는 {@link EventTarget#on} 사용.
*
* @param {문자열|문자열[]} 유형
* 이벤트 이름 또는 이벤트 이름의 배열.
*
* @param {EventTarget~EventListener} fn
* 각 이벤트 이름에 대해 한 번씩 호출되는 함수.
*/
EventTarget.prototype.one = 기능(유형, fn) {
// addEventListener 앨리어싱 Events.on을 제거합니다.
// 무한 유형 루프에 빠지지 않도록
const ael = this.addEventListener;
this.addEventListener = () => {};
Events.one(this, type, fn);
this.addEventListener = ael;
};
EventTarget.prototype.any = 함수(유형, fn) {
// addEventListener 앨리어싱 Events.on을 제거합니다.
// 무한 유형 루프에 빠지지 않도록
const ael = this.addEventListener;
this.addEventListener = () => {};
Events.any(this, type, fn);
this.addEventListener = ael;
};
/**
* 이 함수는 이벤트를 발생시킵니다. 그러면 '이벤트 리스너'가 발생합니다.
* 해당 이벤트를 기다리는 중 호출됩니다. `이벤트 리스너`가 없는 경우
* 이벤트의 경우 아무 일도 일어나지 않습니다.
*
* 트리거되는 `Event`의 이름이 `EventTarget.allowedEvents_`에 있는 경우.
* 트리거는 `on` + `uppercaseEventName` 함수도 호출합니다.
*
* 예:
* '클릭'은 `EventTarget.allowedEvents_`에 있으므로 트리거가 호출을 시도합니다.
* 존재하는 경우 'onClick'.
*
* @param {string|EventTarget~Event|Object} 이벤트
* 이벤트의 이름, `Event` 또는 다음으로 설정된 유형의 키가 있는 객체
* 이벤트 이름.
*/
EventTarget.prototype.trigger = 함수(이벤트) {
상수 유형 = event.type || 이벤트;
// 지원 중단
// 향후 버전에서는 기본 대상을 `this`로 지정해야 합니다.
// 대상을 `elem`으로 기본 설정하는 방법과 비슷합니다.
// `이벤트.트리거`. 현재 기본 `target`은
// `Event.fixEvent` 호출로 인한 `document`.
if (이벤트 유형 === '문자열') {
이벤트 = {유형};
}
이벤트 = Events.fixEvent(이벤트);
if (this.allowedEvents_[유형] && this['on' + 유형]) {
this['on' + type](이벤트);
}
Events.trigger(이, 이벤트);
};
/**
* {@link EventTarget#trigger}의 별칭입니다. `EventTarget`이 모방하도록 허용
* 표준 DOM API.
*
* @기능
* @see {@link EventTarget#trigger}
*/
EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger;
EVENT_MAP하자;
EventTarget.prototype.queueTrigger = 함수(이벤트) {
// EVENT_MAP이 사용될 경우에만 설정
if (!EVENT_MAP) {
EVENT_MAP = 새 지도();
}
상수 유형 = event.type || 이벤트;
let map = EVENT_MAP.get(이);
if (!맵) {
지도 = 새 지도();
EVENT_MAP.set(이것, 지도);
}
const oldTimeout = map.get(유형);
지도.삭제(유형);
window.clearTimeout(oldTimeout);
const timeout = window.setTimeout(() => {
지도.삭제(유형);
// 현재 대상에 대한 모든 시간 제한을 지운 경우 해당 맵을 삭제합니다.
if (지도 크기 === 0) {
지도 = null;
EVENT_MAP.delete(이);
}
this.trigger(이벤트);
}, 0);
map.set(타입, 타임아웃);
};
기본 EventTarget 내보내기;