Skip to content

Instantly share code, notes, and snippets.

@diago
Created March 25, 2010 16:27
Show Gist options
  • Save diago/343769 to your computer and use it in GitHub Desktop.
Save diago/343769 to your computer and use it in GitHub Desktop.
var Dispatcher = (function(){
var Dispatcher = Class.create();
Dispatcher.Version = '1.0.0';
Dispatcher.options = {};
Dispatcher.instance = undefined;
Dispatcher.prototype = {
initialize: function(options){
this.options = {};
Object.extend(this.options, Dispatcher.options);
Object.extend(this.options, options || {});
this.events = $H();
this.doEventHandler = this.doEvent.bindAsEventListener(this);
},
/**
* Adds an event to the dispatcher
*
* @param onEvent string The event to add. 'click' or whatever
* @param selector string CSS selector to use to find the target element
* @param callback function Callback function to trigger.
* @param once boolean If true the event will be removed from the dispatcher after the first run
*
*/
add: function(onEvent, selector, callback, once){
var callbacks,
selectors = this.events.get(onEvent);
if( ! selectors){
selectors = this.events.set(onEvent, $H());
callbacks = selectors.set(selector, []);
Event.observe(document, onEvent, this.doEventHandler);
} else {
callbacks = selectors.get(selector) || [];
}
callbacks.push({
callback: callback,
once: once
});
selectors.set(selector, callbacks);
this.events.set(onEvent, selectors);
},
/**
* Removes a callback from a selector, selector from an event,
* or the entire event
*
* @param onEvent string Event to work with: 'click'
* @param selector string Selector to work with. If no selector is provided the entire event is removed.
* @param callback function The callback to remove
*/
remove: function(onEvent, selector, callback){
var selectors = this.events.get(onEvent),
callbacks = selectors.get(selector),
index;
if(callback){
index = callbacks.indexOf(callback);
// remove the callback
callbacks.splice(index, 1);
// if there is no more callbacks remove the selector
if(callbacks.length < 1) selectors.unset(selector);
}
// if no selector was passed in or
// there are no more selectors remove the
// onEvent from the document and events hash
if( ! selector || selectors.keys().length < 1){
this.events.unset(onEvent);
Event.stopObserving(document, onEvent, this.doEventHandler);
} else this.events.set(onEvent, selectors);
},
doEvent: function(event){
var selectors = this.events.get(event.type),
callbacks, target;
selectors.keys().each(function(selector){
if(target = event.findElement(selector)){
callbacks = selectors.get(selector);
for(var x=0, l=callbacks.length; x<l; x++){
callback = callbacks[x];
callback.callback.call(target, event);
if(callback.once) this.remove(event.type, selector, callback);
}
}
}.bind(this));
}
};
// return a singleton
return (function(){
if( ! Dispatcher.instance){
Dispatcher.instance = new Dispatcher();
}
return Dispatcher.instance;
})();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment