-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathevent.js
150 lines (150 loc) · 4.88 KB
/
event.js
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//#region Event
/**
* Waits until a condition is met then resolves a promise.
* @returns {Promise} A promise resolved when the condition returned by the function is true.
* @memberOf event
* @function
* @example
* //Waits until the current second of the current minute is 10.
* _$.waitUntil(() => new Date().getSeconds === 10).then(() => console.log("Done"))
* @example
* //This DOES NOT work
* _$.waitUntil(() => Date.now() === Date.now() + 100);
* //Because it is evaluated many times, and the current date, is never ahead of itself. Therefore in this case the function will run infinitely.
* //To fix this problem and cancel the function after a certain amount of time,
* //you can pass another argument to the function
* _$.waitUntil(() => false, 10000);//Waits 10 seconds, because the function always returns false.
* @param {Function} condition The function which returns true when the condition is met
* @param {Number} [wait=Infinity] The wait time in milliseconds to cancel the function and reject the promise.
*/
export let waitUntil = async (
condition = req("function", "condition"),
wait = Infinity,
) => {
return new Promise(async (resolve, reject) => {
let startTime = Date.now();
while (!condition()) {
if (Date.now() - startTime >= wait) {
reject(condition());
return;
}
await new Promise((res) => requestAnimationFrame(res));
}
resolve(condition());
return condition();
});
};
/**
* Returns the callback when a a click is registered outside the selected element
* @function
* @memberOf event
* @param {Element} element The element to use as the outsideclick element.
* @param {Function} callback The function to run when a click is registered outside the specified element.
* @example
* _$.onOutsideClick(document.querySelector("div"), () => {alert("You clicked outside the DIV!")});
* @returns {Promise} A promise that is resolved when the user clicks outside the specified element.
*/
export let onOutsideClick = (
element = req("HTMLElement", "element"),
callback = req("function", "callback"),
) => {
node();
return new Promise((resolve, reject) => {
document.addEventListener("click", (e) => {
if (!element.contains(e.target)) {
callback();
resolve();
}
});
});
};
/**
* @callback scrollStopCallback
* @param {UIEvent} event The event object
* @returns {undefined}
*/
/**
* Returns the callback when the user stops scrolling.
* @function
* @memberOf event
* @param {HTMLElement} [element=window] The HTML element to listen on for scroll stop.
* @param {Function} callback The callback to call when the user stops scrolling.
* @param {Number} [time=150]
* @example
* _$.onScrollStop(() => {alert("You stopped scrolling!")})
* @returns {Promise} Returns a promise that is resolved when the user stops scrolling.
*/
export let onScrollStop = (
element = window,
callback = req("function", "callback"),
time = 150,
) => {
let isScrolling;
node();
return new Promise((resolve, reject) => {
element.addEventListener(
"scroll",
(e) => {
clearTimeout(isScrolling);
isScrolling = setTimeout(() => {
callback(e);
resolve(e);
}, time);
},
false,
);
});
};
/**
* A lot like socket.io, this allows emit, on and off handlers. (Note that this is local, only your computer sends and recieves your data. Still useful though)
* @memberOf event
* @function
* @returns {Object} The object with the emit, on and off functions in it.
* @example
* let thing = _$.hub();
* // Log any new data to the console
* thing.on("data", (data) => console.log(data));
* setTimeout(() => {
* thing.emit("data", "Yay! Some data!!"); // Logs "Yay! Some data!!" to the console after 2 seconds.
* }, 2000)
*/
export let hub = () => ({
hub: Object.create(null),
emit(event, data) {
(this.hub[event] || []).forEach((handler) => handler(data));
},
on(event, handler) {
if (!this.hub[event]) this.hub[event] = [];
this.hub[event].push(handler);
},
off(event, handler) {
const i = (this.hub[event] || []).findIndex((h) => h === handler);
if (i > -1) this.hub[event].splice(i, 1);
if (this.hub[event].length === 0) delete this.hub[event];
},
});
/**
* Dispatches an event of the type specified with custom arguments.
* @memberOf event
* @function
* @example
* //Dispatch a custom mouse move event to the window.
* _$.dispatch("mousemove", {clientX: 100, clientY: 150, target: document.documentElement}, window);
* @param {String} type The type of event to dispatch (E.g. "mousemove")
* @param {Object} args The argument representing the event, e.g. {clientX: 100, clientY: 150}
* @param {EventTarget} [target=window] What to dispatch the event to.
* @returns {Event} The event object.
*/
export let dispatch = (
args = req("object", "event properties"),
type = req("string", "type"),
target = window,
) => {
let e = new Event(type);
for (let o in args) {
e[o] = args[o];
}
target.dispatchEvent(e);
return e;
};
//#endregion Event