-
-
Save anutron/39747 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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