-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnamespaced-event-delegation.ts
79 lines (66 loc) · 2.37 KB
/
namespaced-event-delegation.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
import EventManager from './event-manager';
interface EventLabels {
events: string;
elements: string;
}
interface DelegatedEvent extends EventLabels {
handler: Function;
targets?: string;
once?: boolean;
}
export default class NamespacedEventDelegation extends EventManager {
public on = ({ events, elements, targets, handler, once = false }: DelegatedEvent) => {
this.candidates(elements, events, (element, eventNamespace) => {
element.addEventListener(
this.extractEventName(eventNamespace),
this.addEvent(element, eventNamespace, (originalEvent) => {
let handlerParams = {
event: eventNamespace,
delegatedTarget: element,
currentTarget: element,
originalEvent
};
if (targets) {
const target = originalEvent.target.closest(targets);
if (!target) {
return false;
}
handlerParams = {
...handlerParams,
currentTarget: target || handlerParams.delegatedTarget
};
}
return handler(handlerParams);
}),
{ once }
);
});
};
public once = ({ events, elements, targets, handler }: DelegatedEvent) =>
this.on({ events, elements, targets, handler, once: true });
public off = ({ elements, events }: EventLabels): boolean[] => {
const removed = [];
this.getEvents().forEach((storedEvent) => {
this.candidates(elements, events, (element, event) => {
element.removeEventListener(this.extractEventName(event), storedEvent.handler);
removed.push(this.removeEvents(element, event));
});
});
return removed;
};
public fire = ({ elements, events }: EventLabels): boolean[] => {
const fired = [];
const evt = document.createEvent('Event');
this.candidates(elements, events, (element, event) => {
evt.initEvent(this.extractEventName(event), true, true);
fired.push(element.dispatchEvent(evt));
});
return fired;
};
private candidates = (elements, events, fn) => {
const elementsArr = typeof elements === 'string' ? document.querySelectorAll(elements) : [elements];
const eventsArr = events.split(' ');
elementsArr.forEach((element) => eventsArr.forEach((event) => fn(element, event)));
};
private extractEventName = (eventName) => eventName.split('.')[0];
}