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?

1 Answer 1

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).

Sign up to request clarification or add additional context in comments.

3 Comments

this is great, after all these years still a very good solution :)
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?
Readability, sure, why favor cleverness? But also, technically, you're accessing this._events twice there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.