Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use JavaScript EventTarget?

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

like image 509
Mulan Avatar asked Mar 05 '14 01:03

Mulan


People also ask

What is JavaScript EventTarget?

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.

How do you target an element in JavaScript?

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');

What is E target value in JS?

Thus e. target. value is the value property of some DOM element, in this case that means the text entered in the search input.

How does event listener work in JavaScript?

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.


1 Answers

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

like image 93
Mulan Avatar answered Sep 27 '22 18:09

Mulan