var Events = new EventManager(); function EventManager() { var reg = null; } /** * Attach an event listener to an object * * @param object The object you want to attach to * @param string The event type * @param function The listener function */ EventManager.prototype.add = function(obj, evType, fn) { evType = this.checkType(evType); this.initElm(obj, evType); obj[evType] = this.genListener(obj.id, evType, fn); } /** * Remove an event listener from an object * * @param object The object to remove from * @param string The event type the listener is attached to * @param function The function to remove */ EventManager.prototype.remove = function(obj, evType, fn) { evType = this.checkType(evType); this.initElm(obj, evType); del = this.reg.inArray(fn); if(del == -1) return; this.reg.splice(del, 1); obj[evType] = this.genListener(obj.id, evType); } /** * Generate the anonymous listener function * * To create a "virtual" event manager, we must create custom anonymous * functions to call the other listener functions attached to an object. This * method goes through the attached listeners and automatically generates * the new anonymous function. * * @param string The ID of the object you are generating for * @param string The event type you are generating for * @param function (Opt) The function you want to add */ EventManager.prototype.genListener = function(id, evType, fn) { if(typeof fn == 'function') this.reg[id][evType].push(fn); if(this.reg[id][evType].length == 1) new_func = this.reg[id][evType][0]; else { var eval_str = 'var func; '; for(var i = 0; i < this.reg[id][evType].length; i++) { eval_str += 'func = Events.reg[\'' + id + '\'][\'' + evType + '\'][' + i + ']; func.call(getElm(\'' + id + '\'), e); '; } eval('var new_func = function(e) { ' + eval_str + '};'); } return new_func; } /** * Initiate an element with the registry * * - Creates a random, unique ID for this element if it does not have one * - Creates a place in the registry if it does not exist * - Creates a new event array in the registry if it does not exist * * @param object The object to use * @param string The event to use */ EventManager.prototype.initElm = function(obj, evType) { if(!obj.id) obj.id = this.genUniqueId(); if(!this.reg) this.reg = new Array(); if(!this.reg[obj.id]) this.reg[obj.id] = new Array(); if(!this.reg[obj.id][evType]) { this.reg[obj.id][evType] = new Array(); if(obj[evType]) this.reg[obj.id][evType].push(obj[evType]); } } /** * Check to make sure the event type has the 'on' prefix * * @param string The event string to check */ EventManager.prototype.checkType = function(evType) { if(evType.substring(0, 2) != 'on') return 'on' + evType; else return evType; } /** * Generate a unique ID to use */ EventManager.prototype.genUniqueId = function() { var date = new Date(); var id; do { id = 'ID_' + (date.valueOf() + (Math.floor(100 * Math.random())) + (Math.floor(100 * Math.random())) ); } while(getElm(id)); return id; }