naomik naomik - 2 months ago 16x
Javascript Question

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() {;

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?


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


I gave up on this awhile ago, but recently needed it again. Here's what I ended up using.


class Emitter {
  constructor() {
    var delegate = document.createDocumentFragment();
    ].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'))


function Emitter() {
  var eventTarget = document.createDocumentFragment()

  function delegate(method) {
    this[method] = eventTarget[method].bind(eventTarget)

  ].forEach(delegate, this)

// sample class to use it
function Example() {

// run it
var e = new Example()

e.addEventListener("something", function(event) {

e.dispatchEvent(new Event("something"))


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