Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anutron/39714 to your computer and use it in GitHub Desktop.
Save anutron/39714 to your computer and use it in GitHub Desktop.
/*
Script: Element.Delegate.js
Extends the Element native object to include the delegate method for more efficient event management.
License:
http://www.clientcide.com/wiki/cnet-libraries#license
*/
(function(){
var getType = function(type) {
if ($type(type) != "string") return type;
var custom = Element.Events.get(type);
return custom ? custom.base : type;
};
var checkOverOut = function(el, e){
if (el == e.target || el.hasChild(e.target)) {
var related = e.relatedTarget;
if (related == undefined) return true;
if (related === false) return false;
return ($type(el) != 'document' && related != el && related.prefix != 'xul' && !el.hasChild(related));
}
};
function check(e, test) {
var target = e.target;
var isOverOut = /^(mouseover|mouseout)$/.test(e.type);
var els;
if ($type(test) == 'string') els = this.getElements(test);
else if ($type(test) == 'array') els = test;
var match = els.indexOf(target);
if (match >= 0) return els[match];
for (var i = els.length; i--; ) {
var el = els[i];
if (el == target || el.hasChild(target)) {
return (!isOverOut || checkOverOut(el, e)) ? el : false;
}
}
}
Element.implement({
delegate: function(test, type, fn) {
if ($type(type) == 'object') {
$each(type, function(f, t) {
this.delegate(test, t, f);
}, this)
return this;
}
type = getType(type);
var isOverOut = /^(mouseover|mouseout)$/.test(type);
var fns = this.retrieve('delegates', []);
fns.push(fn);
var wraps = this.retrieve('delegations', []);
var tester;
switch($type(test)) {
case 'string':
tester = function(e) {
return check.call(this, e, test);
}.bind(this); break;
case 'function':
tester = test; break;
case 'array':
tester = function(e) {
return check.call(this, e, test);
}.bind(this); break;
}
var wrapper = function(e) { var el = tester(e); if (el) fn.call(el, e, el); };
wraps.push(wrapper);
return this.addEvent(type, wrapper);
},
unDelegate: function(type, fn) {
var fns = this.retrieve('delegates', []);
var index = fns.indexOf(fn);
if (index == -1) return this;
var wraps = this.retrieve('delegations', []);
var fn = wraps[index];
if (!fn) return this;
wraps.splice(index, 1);
fns.splice(index, 1);
this.store('delegations', wraps).store('delegates', fns);
return this.removeEvent(getType(type), fn);
}
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment