Last active
April 27, 2021 11:07
-
-
Save choegyumin/fdd690d609990e695dd6c80ced60a6ee to your computer and use it in GitHub Desktop.
Namespacing Event Listener in Vanilla Javascript (:see_no_evil: Monkey Patch)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
'use strict'; | |
EventTarget.prototype.on = function (event, listener, options) { | |
if (arguments.length < 2) | |
throw new TypeError("Failed to execute 'on' on 'EventTarget': 2 arguments required, but only " + arguments.length + " present."); | |
var typeOfListener = typeof listener; | |
if (typeOfListener !== 'function' && typeOfListener !== 'object') | |
throw new TypeError("Failed to execute 'on' on 'EventTarget': The callback provided as parameter 2 is not an object."); | |
if (!this.hasOwnProperty('listeners')) | |
Object.defineProperty(this, 'listeners', { | |
value: [], | |
configurable: false, | |
enumerable: true, | |
writable: false | |
}); | |
event = String(event).trim(); | |
var eventStruct = event.split('.'); | |
this.listeners.push({event: event, listener: listener}); | |
this.addEventListener(eventStruct[0], listener, options); | |
return this; | |
}; | |
EventTarget.prototype.off = function (event, options) { | |
if (arguments.length < 1) | |
throw new TypeError("Failed to execute 'off' on 'EventTarget': 1 arguments required, but only " + arguments.length + " present."); | |
if (!this.hasOwnProperty('listeners')) return this; | |
event = String(event).trim(); | |
var eventStruct = event.split('.'); | |
var type = eventStruct[0]; | |
var namespace = eventStruct[1]; | |
var isTypeOnly = eventStruct.length === 1; | |
var isNamespaceOnly = eventStruct.length > 1 && type.length === 0; | |
var _idx = this.listeners.length; | |
while (_idx--) { | |
var _obj = this.listeners[_idx], _event = _obj.event, _listener = _obj.listener; | |
if (event === _event) { | |
this.removeEventListener(type, _listener, options); | |
this.listeners.splice(_idx, 1); | |
} else if (isTypeOnly || isNamespaceOnly) { | |
var _eventStruct = _event.split('.'), _type = _eventStruct[0], _namespace = _eventStruct[1]; | |
if (isTypeOnly | |
? (type !== _type) | |
: (namespace !== _namespace)) continue; | |
this.removeEventListener(_type, _listener, options); | |
this.listeners.splice(_idx, 1); | |
} | |
} | |
return this; | |
}; | |
})(); |
for Typescript
// index.d.ts
interface EventTarget {
listeners?: {
event: string,
listener: EventListenerOrEventListenerObject
}[];
on(event: string, listener: EventListenerOrEventListenerObject | null, options?: boolean | AddEventListenerOptions): this;
off(event: string, options?: EventListenerOptions | boolean): this;
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage