Skip to content

Instantly share code, notes, and snippets.

@francois-dibulo
Last active March 12, 2018 09:40
Show Gist options
  • Save francois-dibulo/07dbebdf56269e44a911b492083b1acd to your computer and use it in GitHub Desktop.
Save francois-dibulo/07dbebdf56269e44a911b492083b1acd to your computer and use it in GitHub Desktop.
/**
* EventHandler.js
*
* @description Extends object with .on(), .off() and .emit() methods
* @author: francois@n-dream.com
* @constructor
* @param {Object} source - The object to extend with events
*/
var EventHandler = function() {
var EventHandler = function(source) {
this.source = source;
this.events = {};
this.bindHandler(source);
};
/**
* Resets the entire EventHandler
*/
EventHandler.prototype.reset = function() {
this.events = {};
this.source.on = null;
this.source.off = null;
this.source.emit = null;
};
/**
* Extends the source object with event handler functions
*/
EventHandler.prototype.bindHandler = function(source) {
this.source.on = this.on.bind(this);
this.source.off = this.off.bind(this);
this.source.emit = this.emit.bind(this);
};
/**
* @param {String} event_name - Name of the event to trigger
* @param {Function} callback - The callback function to call when emits is called
* @return {String} - An id. Store it to be able to call .off(id)
*/
EventHandler.prototype.on = function(event_name, callback) {
if (!event_name) throw "Missing param event_name.";
if (typeof callback !== 'function') throw "Event callback is not a function";
if(!this.events[event_name]) {
this.events[event_name] = {};
}
var id = this.getRandomId();
this.events[event_name][id] = callback;
return id;
};
/**
* Removes a previously bounded function from the events
* @param {String} event_name - Name of the event to trigger
*/
EventHandler.prototype.off = function(id) {
if (!id) throw "Missing param id";
var events = this.events;
for (var evt_name in events) {
for (var evt_id in events[evt_name]) {
if (evt_id === id) {
this.events[evt_name][evt_id] = null;
delete this.events[evt_name][evt_id];
}
}
}
};
/**
* Dispatches the event by event name
* @param {String} event_name - Name of the event to trigger
* @param {Mixed} params - The params to pass to the callback function
*/
EventHandler.prototype.emit = function(event_name, params) {
if (!event_name) throw "Missing param event_name.";
var evts = this.events[event_name];
if (evts) {
for (var id in evts) {
var fn = evts[id];
if (typeof fn === 'function') {
fn.call(this.source, this.source, params);
} else {
console.warn("Failed to emit function:", event_name);
}
}
}
};
/**
* Returns random generated Id
* @return {String}
*/
EventHandler.prototype.getRandomId = function(chars) {
chars = Math.max(2, Math.min(chars || 15, 36));
return (Math.random() + 1).toString(36).substring(2, chars);
};
return EventHandler;
}();
// Some custom object:
var MyCustomObj = function() {
this.event_handler = new EventHandler(this);
};
MyCustomObj.prototype = {
// Emit event
startParty: function() {
this.emit("ON_PARTY", { "beer" : true });
}
};
var my_obj = new MyCustomObj();
// Listen for the event
var event_id = my_obj.on("ON_PARTY", function(source_object, params) {
if (params && params.beer) {
console.log("Yay beer!");
}
};
// Trigger event
my_obj.startParty();
// Unsubscribe event
my_obj.off(event_id);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment