Skip to content

Instantly share code, notes, and snippets.

@anutron
Forked from subtleGradient/README.js
Created December 24, 2008 18:52
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/39747 to your computer and use it in GitHub Desktop.
Save anutron/39747 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.
Based on the work of Daniel Steigerwald.
"Element.Delegate": {
"deps":["Element.Event"],
"desc":"Delegates events for child elements to their parents for greater efficiency."
},
License:
http://www.clientcide.com/wiki/cnet-libraries#license
*/
(function(){
var getType = function(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 = this.getElements(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({
relayEvent: function(test, type, fn) {
if ($type(type) == 'object') {
$each(type, function(f, t) {
delegate.call(this, test, t, f);
}, this);
return this;
}
test.eventType = type;
type = getType(type);
var isOverOut = /^(mouseover|mouseout)$/.test(type);
var fns = this.retrieve('delegate:fns', []);
var wraps = this.retrieve('delegate:wrappers', []);
fns.push(fn);
var wrapper = function(e) { var el = check.call(this, e, test); if (el) fn.call(el, e, el); };
wraps.push(wrapper);
return this.addEvent(type, wrapper);
},
relayEvents: function(relays) {
for (relay in relays) {
var events = relays[relay];
for (event in events) {
this.relayEvent(event, events[event], relay);
}
}
return this;
},
unrelayEvent: function(type, fn) {
var fns = this.retrieve('delegate:fns', []);
var wraps = this.retrieve('delegate:wrappers', []);
var index = fns.indexOf(fn);
if (index == -1) return this;
var fn = wraps[index];
if (!fn) return this;
wraps.splice(index, 1);
fns.splice(index, 1);
return this.removeEvent(getType(type), fn);
},
unrelayEvents: function(relays) {
if ($type(relays)=="string") {
//now what?
})
for(relay in relays) {
var events = relays[relay];
for (event in events) {
this.unrelayEvent(event, events[event]);
}
}
return this;
}
});
var delegate = ;
var undelegate = ;
var oldAddEvent = Element.prototype.addEvent,
oldAddEvents = Element.prototype.addEvents,
oldRemoveEvent = Element.prototype.removeEvent,
oldRemoveEvents = Element.prototype.removeEvents;
Element.implement({
addEvent: function(type, fn, filter){
if ($type(filter) == "string") return oldAddEvent.apply(this, arguments);
return this.relayEvent(type, fn, filter);
},
removeEvent: function(type, fn){
var fns = this.retrieve('delegate:fns', []);
if (fns.contains(fn)) {
var t = Element.Events.get(type);
if (!t) {
$each(Element.NativeEvents, function(v, k){
if (k == type) t = k;
});
}
this.removeEvent(t, fn);
return this;
} else {
return oldRemoveEvent.apply(this, arguments);
}
},
addEvents: function(events, filter) {
if ($type('filter') != "string") return oldAddEvents.apply(this, arguments);
for (var event in events) this.relayEvents(event, events[event], filter);
return this;
},
removeEvents: function(events){
if (($type(events) == 'object')) {
for (var type in events) this.unrelayEvent(type, events[type]);
} else {
return oldRemoveEvents.apply(this, arguments);
}
return this;
}
});
Element.Properties.oldEvents = Element.Properties.events;
Element.Properties.events = {
/*
{
click: fn
}
OR
{
selector: {
click: fn
}
}
*/
set: function(events) {
for (event in events) {
if ($type(events[event]) == "function") this.set({oldEvents:events});
else this.relayEvents(events[event], event);
}
}
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment