55
66import DOMHelper from '../helpers/dom.js'
77
8- class EventHelper {
8+ export class EventHelper {
99 /**
1010 * Add event listener with namespace support
1111 * @param {Element|string } element - DOM element or selector
@@ -270,36 +270,73 @@ class EventHelper {
270270 */
271271 static offAll ( element , namespace ) {
272272 if ( typeof element === 'string' ) element = DOMHelper . $ ( element )
273- if ( ! element || ! element . _eventHandlers ) return element
273+ if ( ! element ) return element
274+
275+ // Clean up non-delegated event handlers first
276+ if ( element . _eventHandlers ) {
277+ // Iterate through all event types
278+ Object . keys ( element . _eventHandlers ) . forEach ( eventType => {
279+ if ( namespace ) {
280+ // Remove only handlers matching the namespace
281+ element . _eventHandlers [ eventType ] = element . _eventHandlers [ eventType ] . filter ( info => {
282+ if ( info && info . namespace === namespace ) {
283+ element . removeEventListener ( eventType , info . wrappedHandler , info . options )
284+ return false
285+ }
286+ return true
287+ } )
288+ } else {
289+ // Remove all handlers for this event type
290+ element . _eventHandlers [ eventType ] . forEach ( info => {
291+ if ( info ) {
292+ element . removeEventListener ( eventType , info . wrappedHandler , info . options )
293+ }
294+ } )
295+ element . _eventHandlers [ eventType ] = [ ]
296+ }
274297
275- // Iterate through all event types
276- Object . keys ( element . _eventHandlers ) . forEach ( eventType => {
298+ // Clean up empty event type arrays
299+ if ( ! element . _eventHandlers [ eventType ] || element . _eventHandlers [ eventType ] . length === 0 ) {
300+ delete element . _eventHandlers [ eventType ]
301+ }
302+ } )
303+
304+ // Clean up if no handlers left at all
305+ if ( Object . keys ( element . _eventHandlers ) . length === 0 ) {
306+ delete element . _eventHandlers
307+ }
308+ }
309+
310+ // Also clean up any delegated handlers tied to this element
311+ if ( element . _delegates ) {
277312 if ( namespace ) {
278- // Remove only handlers matching the namespace
279- element . _eventHandlers [ eventType ] = element . _eventHandlers [ eventType ] . filter ( info => {
280- if ( info . namespace === namespace ) {
281- element . removeEventListener ( eventType , info . wrappedHandler , info . options )
313+ // Remove only delegates matching the namespace
314+ element . _delegates = element . _delegates . filter ( delegate => {
315+ if ( delegate . namespace === namespace ) {
316+ // Remove the underlying event listener
317+ const eventWithNamespace = delegate . namespace
318+ ? `${ delegate . eventType } .${ delegate . namespace } `
319+ : delegate . eventType
320+ this . off ( element , eventWithNamespace , delegate . handler )
282321 return false
283322 }
284323 return true
285324 } )
286325 } else {
287- // Remove all handlers for this event type
288- element . _eventHandlers [ eventType ] . forEach ( info => {
289- element . removeEventListener ( eventType , info . wrappedHandler , info . options )
326+ // Remove all delegates
327+ element . _delegates . forEach ( delegate => {
328+ const eventWithNamespace = delegate . namespace
329+ ? `${ delegate . eventType } .${ delegate . namespace } `
330+ : delegate . eventType
331+ this . off ( element , eventWithNamespace , delegate . handler )
290332 } )
291- element . _eventHandlers [ eventType ] = [ ]
333+ element . _delegates = [ ]
292334 }
293335
294- // Clean up empty event type arrays
295- if ( element . _eventHandlers [ eventType ] . length === 0 ) {
296- delete element . _eventHandlers [ eventType ]
336+ // Clean up delegates storage if no delegates remain
337+ if ( element . _delegates . length === 0 ) {
338+ delete element . _delegates
297339 }
298- } )
299-
300- // Clean up if no handlers left at all
301- if ( Object . keys ( element . _eventHandlers ) . length === 0 ) {
302- delete element . _eventHandlers
303340 }
304341
305342 return element
@@ -308,7 +345,9 @@ class EventHelper {
308345 /**
309346 * Native DOM helper methods
310347 */
311- static $ = DOMHelper . $ . bind ( DOMHelper )
348+ static $ ( ...args ) {
349+ return DOMHelper . $ . apply ( DOMHelper , args )
350+ }
312351
313352 /**
314353 * Find parent element matching selector
@@ -344,7 +383,7 @@ class EventHelper {
344383 * Get data attribute value
345384 * @param {Element|string } element - DOM element or selector
346385 * @param {string } key - Data key
347- * @returns {string|null } The data attribute value or null
386+ * @returns {string|undefined| null } The data attribute value, undefined if the key is missing, or null if the element is not found
348387 */
349388 static getData ( element , key ) {
350389 if ( typeof element === 'string' ) element = DOMHelper . $ ( element )
@@ -368,5 +407,3 @@ class EventHelper {
368407 return element
369408 }
370409}
371-
372- export default EventHelper
0 commit comments