I've been watching the threads discussing event delegation as I think
it's a great way to speed up apps.
All of the solutions I've seen take a similar approach in using a CSS
selector to match elements for the event, and a parent element to
attach the event to.
I thought I'd try a different approach, namely using a single event
attached to the document and using an API identical to Event.observe
to register the events.
My first bash at this code is below, a fair bit of lifted from
Prototype's event handling. I've called this Event.register rather
than Event.delegate to avoid any confusion in the differing approach
to other event delegation.
// Event.register
Object.extend(Event, (function(){
var registerable = $w('click mouseover');
var cache = {};
function getEventID(element) {
if (element._prototypeEventID) return element._prototypeEventID
[0];
arguments.callee.id = arguments.callee.id || 1;
return element._prototypeEventID = [++arguments.callee.id];
}
function getCacheForID(id) {
return cache[id] = cache[id] || { };
}
function getWrappersForEventName(id, eventName) {
var c = getCacheForID(id);
return c[eventName] = c[eventName] || [];
}
function dispatch(e){
var element = e.target;
while(!e.stopped && element && element.nodeType == 1){
var id = getEventID(element);
var c = getWrappersForEventName(id, e.type);
c.invoke('call', this, e);
element = element.up();
}
}
function initialize(e){
registerable.each(function(eventName){
document.observe(eventName, dispatch);
});
}
function register(element, eventName, handler){
var id = getEventID(element);
var c = getWrappersForEventName(id, eventName);
if (c.pluck("handler").include(handler)) return false;
var wrapper = function(event){
handler.call(element, event);
};
wrapper.handler = handler;
c.push(wrapper);
return wrapper;
}
document.observe('dom:loaded', initialize);
return {
register : function(element, eventName, callback){
element = $(element);
if(registerable.include(eventName)){
register(element, eventName, callback);
return element
}else{
return Event.observe(element, eventName, callback);
}
}
};
})());
// Example usage
function log(e){
console.log(e.target);
}
$$('a').each(function(link){
Event.register(link, 'click', log);
});
I'd be interested to hear any feedback about my approach, in
particular about any potential performance pitfalls this may cause.
It's a first bash, and I've not tested it outside of Firefox.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Prototype: Core" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/prototype-core?hl=en
-~----------~----~----~----~------~----~------~--~---