From 49520931facf057cbf257f3af718d545fda5933c Mon Sep 17 00:00:00 2001 From: Mateus Souza Date: Tue, 22 Mar 2022 00:46:40 -0300 Subject: [PATCH] Events switched to per element list, with optional off callback parameter --- src/core/events.ts | 82 ++++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 31 deletions(-) diff --git a/src/core/events.ts b/src/core/events.ts index b73fba0..0772872 100644 --- a/src/core/events.ts +++ b/src/core/events.ts @@ -6,7 +6,9 @@ declare interface Trigger { callback: Function } -let _events: Array = [] +declare interface WithEvents extends EventTarget { + __events?: Array +} /** * Attach event to element @@ -20,7 +22,7 @@ function _event( action: "add" | "remove", element: any, event: string, - selector: string | Function, + selector?: string | Function, callback?: Function ) { @@ -34,11 +36,16 @@ function _event( return } - const items = element instanceof Window ? [element] : $$(element) let handler: Function // Determine handler - if (callback === undefined) { + if (callback === undefined && selector === undefined) { + + // None + handler = null + selector = null + + } else if (callback === undefined) { // Bind handler = selector @@ -59,46 +66,59 @@ function _event( const split = event.split('.') const theEvent = split.shift() const namespace = split.join('.') + const items: Array = element instanceof Window ? [element] : $$(element) + + if (action === 'add' && typeof handler === 'function') { - if (action === 'add') { + for (const item of items) { - _events.push({ - event: theEvent, - namespace: namespace, - callback: handler - }) + if (!item.__events) { + item.__events = [] + } + + item.__events.push({ + event: theEvent, + namespace: namespace, + callback: handler + }) - items.forEach((item: Node | Window) => { item.addEventListener( theEvent, handler.bind(item), false ) - }) - return handler - } + } - _events = _events.filter((watcher) => { + } else if (action === 'remove') { - const pass = Boolean( - theEvent !== watcher.event - && (namespace === '' || namespace !== watcher.namespace) - && (typeof handler !== 'function' || handler !== watcher.callback) - ) + for (const item of items) { - if (!pass) { - items.forEach((item: Node | Window) => { - item.removeEventListener( - watcher.event, - watcher.callback.bind(item), - false + if (!item.__events) { + return + } + + item.__events = item.__events.filter((watcher) => { + const pass = Boolean( + theEvent !== watcher.event + && (namespace === '' || namespace !== watcher.namespace) + && (typeof handler !== 'function' || handler !== watcher.callback) ) + + if (!pass) { + item.removeEventListener( + watcher.event, + watcher.callback.bind(item), + false + ) + } + + return pass }) + } - return pass - }) + } return handler } @@ -121,7 +141,7 @@ function on(element: any, event: string, selector: string | Function, callback?: * @param selector * @param callback */ -function off(element: any, event: string, selector: string | Function, callback?: Function) { +function off(element: any, event: string, selector?: string | Function, callback?: Function) { return _event('remove', element, event, selector, callback) } @@ -142,9 +162,9 @@ function trigger(element: any, event: string, selector?: string) { 'cancelable': true }) - items.forEach((item: Node | Window) => { + for (const item of items) { item.dispatchEvent(theEvent) - }) + } }