6

I'm using Flash a lot and my classes uses EventDispatcher class which allows me to define custom events of a class. How can I do this in JavaScript.

I would like to do something like this:

var MyClass = function() {
};
MyClass.prototype = {
  test : function() {
    dispatchEvent('ON_TEST');
  }
};

var mc = new MyClass();
mc.addEventListener('ON_TEST', handler);
function handler() { alert('working...') }

How is this possible with JavaScript?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
xpepermint
  • 35,055
  • 30
  • 109
  • 163

1 Answers1

20

Gotta roll your own. Here's just one way.

var MyClass = function() {
    this._events = {};
};
MyClass.prototype = {
  addListener: function(eventName, callback) {
      var events = this._events,
          callbacks = events[eventName] = events[eventName] || [];
      callbacks.push(callback);
  },
  raiseEvent: function(eventName, args) {
      var callbacks = this._events[eventName];
      for (var i = 0, l = callbacks.length; i < l; i++) {
          callbacks[i].apply(null, args);
      }
  },
  test : function() {
    this.raiseEvent('ON_TEST', [1,2,3]); // whatever args to pass to listeners
  }
};

You should probably also add a 'removeListener', which would have to find the callback in the array and remove it from the array (or possibly, remove all listeners for an entire event if no callback given).

InfinitiesLoop
  • 14,349
  • 3
  • 31
  • 34
  • this is great, after all these years still a very good solution :) – andyrandy Aug 16 '13 at 16:18
  • quick question, inside addListener, why all the variables? Could you not do `function (eventName, callback) { (this._events[eventName] = this._events[eventName] || []).push(callback); },` ? or is it merely a question of readability? – WORMSS Apr 16 '14 at 14:05
  • Readability, sure, why favor cleverness? But also, technically, you're accessing this._events twice there. – InfinitiesLoop Apr 18 '14 at 03:09