I would like to create a custom event emitter in my client-side programs. I am referencing this (sparse) documentation for EventTarget
My implementation attempt
var Emitter = function Emitter() { EventTarget.call(this); }; Emitter.prototype = Object.create(EventTarget.prototype, { constructor: { value: Emitter } });
My desired usage
var e = new Emitter(); e.addEventListener("hello", function() { console.log("hello there!"); }); e.dispatchEvent(new Event("hello")); // "hello there!"
Where it fails
var e = new Emitter(); // TypeError: Illegal constructor
What am I doing wrong?
Update
The following is possible, but it's a hack that depends on a dummy DOMElement
var fake = document.createElement("phony"); fake.addEventListener("hello", function() { console.log("hello there!"); }); fake.dispatchEvent(new Event("hello")); // "hello there!"
I'd like to know how to do this without having to use the dummy element
The EventTarget interface is implemented by objects that can receive events and may have listeners for them. In other words, any target of events implements the three methods associated with this interface.
To select an HTML ID using JavaScript we need to point to it and then store it as a variable. Here is the one line of JavaScript we need to target this element and store it as a variable: Code from a text editor: const chocolateDescription = document. getElementById('chocolateCupcake');
Thus e. target. value is the value property of some DOM element, in this case that means the text entered in the search input.
The addEventListener() is an inbuilt function in JavaScript which takes the event to listen for, and a second argument to be called whenever the described event gets fired. Any number of event handlers can be added to a single element without overwriting existing event handlers. Syntax: element.
I gave up on this awhile ago, but recently needed it again. Here's what I ended up using.
ES6
class Emitter { constructor() { var delegate = document.createDocumentFragment(); [ 'addEventListener', 'dispatchEvent', 'removeEventListener' ].forEach(f => this[f] = (...xs) => delegate[f](...xs) ) } } // sample class to use Emitter class Example extends Emitter {} // run it var e = new Example() e.addEventListener('something', event => console.log(event)) e.dispatchEvent(new Event('something'))
ES5
function Emitter() { var eventTarget = document.createDocumentFragment() function delegate(method) { this[method] = eventTarget[method].bind(eventTarget) } [ "addEventListener", "dispatchEvent", "removeEventListener" ].forEach(delegate, this) } // sample class to use it function Example() { Emitter.call(this) } // run it var e = new Example() e.addEventListener("something", function(event) { console.log(event) }) e.dispatchEvent(new Event("something"))
Yeah!
For those that need to support older versions of ecmascript, here you go
// IE < 9 compatible function Emitter() { var eventTarget = document.createDocumentFragment(); function addEventListener(type, listener, useCapture, wantsUntrusted) { return eventTarget.addEventListener(type, listener, useCapture, wantsUntrusted); } function dispatchEvent(event) { return eventTarget.dispatchEvent(event); } function removeEventListener(type, listener, useCapture) { return eventTarget.removeEventListener(type, listener, useCapture); } this.addEventListener = addEventListener; this.dispatchEvent = dispatchEvent; this.removeEventListener = removeEventListener; }
The usage stays the same
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With