elexis/lib/$EventTarget.ts
defaultkavy 4c078c26b6
v0.3.0
- remove: class $EventMethod, $Event.
- change: $EventManager rewrite logic.
- change: most $Node base node element generic type have new EM(EventMap) parameter.
- new: $EventTarget.
- change: $Node extends $EventTarget.
- change: mix dom events and $EventManager events into $EventTarget.on().off().once().
- fix: $Container.insert() process synchronous when passing an not async function
- new: $Window element.
- fix: $(document.documentElement) throw error.
- new: $KeyboardManager, $FocusManager, $PointerManager.
- new: $ global methods:
  - $.events() return new $EventManager.
  - $.pointers() return new $PointerManager.
  - $.keys() return new $KeyboardManager.
  - $.focus() return new $FocusManager.
  - $.call()
- change: $Media extends $HTMLElement
- change: $Anchor.href() support $State parameter.
- new: $State.convert()
2024-10-17 11:54:28 +08:00

50 lines
2.9 KiB
TypeScript

import { $EventManager, $EventMap } from "./$EventManager";
export abstract class $EventTarget<$EM extends $EventMap = $EventMap, EM extends GlobalEventHandlersEventMap = GlobalEventHandlersEventMap> {
private domEvents: Partial<{[key in keyof EM]: Map<Function, Function>}> = {};
readonly events = new $EventManager<$EM>();
abstract dom: EventTarget
//@ts-expect-error
on<K extends keyof $EM>(type: K | K[], callback: (...args: $EM[K]) => any): this;
on<K extends keyof EM>(type: K | K[], callback: (event: EM[K], $node: this) => any, options?: AddEventListenerOptions | boolean): this;
on<K extends string>(type: K | K[], callback: (event: Event, $node: this) => any, options?: AddEventListenerOptions | boolean): this;
on<K extends keyof EM>(types: K | K[], callback: (event: EM[K], $node: this) => any, options?: AddEventListenerOptions | boolean) {
types = $.orArrayResolve(types);
for (const type of types) {
if (!this.domEvents[type]) this.domEvents[type] = new Map()
const handler = (e: Event) => { callback(e as EM[K], this); }
this.domEvents[type].set(callback, handler);
this.events.on(type as any, callback);
this.dom.addEventListener(type as string, handler, options);
}
return this;
}
//@ts-expect-error
off<K extends keyof $EM>(type: K, callback: (...args: $EM[K]) => any): this;
off<K extends keyof EM>(type: K, callback: (event: EM[K], $node: this) => any, options?: AddEventListenerOptions | boolean): this;
off<K extends string>(type: K, callback: (event: Event, $node: this) => any, options?: AddEventListenerOptions | boolean): this;
off<K extends keyof EM>(type: K, callback: (event: EM[K], $node: this) => any, options?: AddEventListenerOptions | boolean) {
const middleCallback = this.domEvents[type]?.get(callback);
if (middleCallback) this.dom.removeEventListener(type as string, middleCallback as EventListener, options);
this.events.off(type as any, callback);
return this;
}
//@ts-expect-error
once<K extends keyof $EM>(type: K, callback: (...args: $EM[K]) => any): this;
once<K extends keyof EM>(type: K, callback: (event: EM[K], $node: this) => any, options?: AddEventListenerOptions | boolean): this;
once<K extends string>(type: K, callback: (event: Event, $node: this) => any, options?: AddEventListenerOptions | boolean): this;
once<K extends keyof EM>(type: K, callback: (event: EM[K], $node: this) => any, options?: AddEventListenerOptions | boolean) {
const onceFn = (event: Event) => {
this.dom.removeEventListener(type as string, onceFn, options)
callback(event as EM[K], this);
};
this.dom.addEventListener(type as string, onceFn, options);
this.events.once(type as any, callback);
return this;
}
trigger(event: string) { this.dom.dispatchEvent(new Event(event)); return }
}