I would like to create a custom event emitter in my client-side programs. I am referencing this (sparse) documentation for EventTarget
My implementation atte
There are 3 ways to achieve this depending on browser support.
1) EventTarget is now constructable, so just extend it:
class MyEventTarget extends EventTarget {
constructor(){
super()
}
}
2) The DOM 'Node' interface implements EventTarget, so just implement that instead:
function MyEventTarget(){
var target = document.createTextNode(null);
this.addEventListener = target.addEventListener.bind(target);
this.removeEventListener = target.removeEventListener.bind(target);
this.dispatchEvent = target.dispatchEvent.bind(target);
}
MyEventTarget.prototype = EventTarget.prototype;
3) Roll your own (assuming no options arg) & dispatch async:
function MyEventTarget(){
this.__events = new Map();
}
MyEventTarget.prototype = {
addEventListener(type, listener){
var listeners = this.__events.get(type);
if(!listeners){
listeners = new Set();
this.__events.set(type, listeners);
}
listeners.add(listener);
},
removeEventListener(type, listener){
var listeners = this.__events.get(type);
if(listeners){
listeners.delete(listener);
if(listeners.size === 0){
this.__events.delete(type);
}
}
},
dispatchEvent(event){
var listeners = this.__events.get(event.type);
if(listeners){
for(let listener of listeners){
setTimeout(listener.call(null, event), 0);
}
}
}
}
Replace Map()/Set() with {}/[] if required.
All 3 of these options can be tested with:
var target = new MyEventTarget();
target.addEventListener('test', (e) => {console.log(e.detail);}, false);
var event = new CustomEvent('test', {detail : 'My Test Event'});
target.dispatchEvent(event);
Any object that needs to implement your own 'EventTarget' interface can inherit it exactly as the native one does:
function Person(name){
MyEventTarget.call(this);
this.__name = name;
}
Person.prototype = {
__proto__ : MyEventTarget.prototype,
get name(){ return this.__name;}
}