How to use JavaScript EventTarget?

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

Leave a Comment