addEventListener is intended for DOM Elements that implements certain event-related interfaces. If you want an event system on pure JavaScript objects, you are looking for a custom event system. An example would be Backbone.Events in Backbone.js. The basic idea is using an object as a hash to keep track of registered callbacks.

Personally I use this: emitter.

It's a fairly simple and elegant solution - with sweet short method names like on(), off() and emit(). you can either create new instances with new Emitter(), or use Emitter(obj) to mix event capabilities into existing objects. Note this library is written for use with a CommonJS module system, but you can use it anywhere else by removing the module.exports = ... line.


If you don't need true event features(such as bubbling, stopPropagation), then you can implement your own events. addEventListener is just an API of the DOM, so you don't really need it for your own objects outside the DOM. If you want to create an evented pattern around an object, here's a good way to do it that does not require any extra browser APIs and should be very backwards-compatible.

Let's say you have an object where you want a bunch of events to be triggered when the dispatch method is called:

var OurDispatcher, dispatcher;

OurDispatcher = (function() {
  function OurDispatcher() {
    this.dispatchHandlers = [];
  }

  OurDispatcher.prototype.on = function(eventName, handler) {
    switch (eventName) {
      case "dispatch":
        return this.dispatchHandlers.push(handler);
      case "somethingElse":
        return alert('write something for this event :)');
    }
  };

  OurDispatcher.prototype.dispatch = function() {
    var handler, i, len, ref;
    ref = this.dispatchHandlers;
    for (i = 0, len = ref.length; i < len; i++) {
      handler = ref[i];
      setTimeout(handler, 0);
    }
  };

  return OurDispatcher;

})();

dispatcher = new OurDispatcher();

dispatcher.on("dispatch", function() {
  return document.body.innerHTML += "DISPATCHED</br>";
});

dispatcher.on("dispatch", function() {
  return document.body.innerHTML += "DISPATCHED AGAIN</br>";
});

dispatcher.dispatch();

It really doesn't have to be more complicated than that, for the most part. This way you have some decent control over your events and you don't need to worry about backward-compatibility or external libraries because everything there is widely supported. Technically, you could even do without setTimeout and handle your callbacks without any APIs. Anything else like stopPropagation() would have to be handled yourself.

https://jsfiddle.net/ozsywxer/

There are, of course, polyfills for CustomEvent, but unless I need advanced event features, I prefer to wrap my own eventing system into a "class" and extending other classes/functions with it.

Here's the CoffeeScript version, which is what the JavaScript is derived from: https://jsfiddle.net/vmkkbbxq/1/

^^ A bit easier to understand.