generated from davidbonnet/foundation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
once.ts
92 lines (90 loc) 路 3 KB
/
once.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import type { Listener, ListenerOptions, Register, Unregister } from "../types";
/**
* Listens for `event` on `target`, calling `listener(event)` at the first occuring `event`. The `listener` is then unregistered upon the first occurence. The provided `options` are identical to those provided to `addEventListener`.
* Returns a function that removes the `listener` from the `target` for the specified `event`.
*
* @param target The target on which to listen for the event.
* @param event The event name to listen for.
* @param listener The listener callback.
* @param options Options to pass to the listener.
* @returns A function that removes the `listener`.
*/
function once<K extends keyof HTMLElementEventMap>(
target: HTMLElement,
eventName: K,
listener: Listener<HTMLElementEventMap[K]>,
options?: ListenerOptions,
): Unregister;
function once<K extends keyof DocumentEventMap>(
target: Document,
eventName: K,
listener: Listener<DocumentEventMap[K]>,
options?: ListenerOptions,
): Unregister;
function once<K extends keyof WorkerEventMap>(
target: Worker,
eventName: K,
listener: Listener<WorkerEventMap[K]>,
options?: ListenerOptions,
): Unregister;
function once<E extends object>(
target: EventTarget,
eventName: string,
listener: Listener<E>,
options?: ListenerOptions,
): Unregister;
/**
* Returns a function that registers a `listener` with optional `options` for a given `event` on the provided `target`. The `listener` is then unregistered upon the first occurence of the `event`.
*
* @example
* ```typescript
* const register = on(element, "click");
* // Start listening
* const off = register(callback);
* // Stop listening
* off();
* ```
*
* @param target The target on which to listen for the event.
* @param event The event name to listen for.
* @returns Function that registers a `listener` with optional `options`.
*/
function once<K extends keyof HTMLElementEventMap>(
target: HTMLElement,
eventName: K,
): Register<Listener<HTMLElementEventMap[K]>, ListenerOptions>;
function once<K extends keyof DocumentEventMap>(
target: Document,
eventName: K,
): Register<Listener<DocumentEventMap[K]>, ListenerOptions>;
function once<K extends keyof WorkerEventMap>(
target: Worker,
eventName: K,
): Register<Listener<WorkerEventMap[K]>, ListenerOptions>;
function once<E extends object>(
target: EventTarget,
eventName: string,
): Register<Listener<E>, ListenerOptions>;
function once<
T extends HTMLElement | Document | Worker | EventTarget,
K extends string,
>(
target: T,
eventName: K,
listener?: Listener<any>,
options?: ListenerOptions,
): Unregister | Register<Listener<any>, any> {
if (listener === undefined) {
return (listener, options) => once(target, eventName, listener, options);
}
const listenOnce: Listener<any> = (event) => {
listener(event);
off();
};
const off = () => {
target.removeEventListener(eventName, listenOnce, options);
};
target.addEventListener(eventName, listenOnce, options);
return off;
}
export { once };