Skip to content

Instantly share code, notes, and snippets.

@aliang
Forked from RStankov/gist:66568
Created February 19, 2010 03:21
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 aliang/308372 to your computer and use it in GitHub Desktop.
Save aliang/308372 to your computer and use it in GitHub Desktop.
(function(){
function delegateHandler(e){
var element = e.element(), elements = element.ancestors ? element.ancestors().concat([element]) : [element];
((Element.retrieve(this, 'prototype_delegates') || $H()).get(e.eventName || e.type) || []).each(function(pair){
if (element = Selector.matchElements(elements, pair.key)[0])
pair.value.invoke('call', element, e);
});
}
function delegate(element, selector, event, handler){
element = $(element);
var store = Element.retrieve(element, 'prototype_delegates');
if (Object.isUndefined(store)){
Element.store(element, 'prototype_delegates', store = $H());
}
var eventStore = store.get(event);
if (Object.isUndefined(eventStore)){
Event.observe(element, event, delegateHandler);
store.set(event, $H()).set(selector, [handler]);
} else {
(eventStore.get(selector) || eventStore.set(selector, [])).push(handler);
}
return element;
}
function clearEvent(element, store, event){
store.unset(event);
Event.stopObserving(element, event, delegateHandler);
};
function clearSelector(element, store, selector, event, estore){
estore.unset(selector);
if (estore.values().length == 0){
clearEvent(element, store, event);
}
}
// stopDelegating(element[, selector[, event[, handler]]])
function stopDelegating(element, selector, event, handler){
element = $(element);
var store = Element.retrieve(element, 'prototype_delegates');
if (Object.isUndefined(store)) return;
switch(arguments.length){
case 1: store.each(function(pair){ clearEvent(element, store, pair.key); }); break;
case 2: store.each(function(pair){ clearSelector(element, store, selector, pair.key, pair.value); }); break;
case 3:
var estore = store.get(event);
if (estore) clearSelector(element, store, selector, event, estore);
break;
default:
case 4:
var estore = store.get(event);
if (!estore) return;
var sstore = estore.get(selector);
if (sstore){
sstore = sstore.reject(function(c){ return c == handler; });
if (sstore.length > 0){
estore.set(selector, sstore);
} else {
clearSelector(element, store, selector, event, estore);
}
}
}
}
// expose
document.delegate = delegate.methodize();
document.stopDelegating = stopDelegating.methodize();
Event.delegate = delegate;
Event.stopDelegating = stopDelegating;
Element.addMethods({ delegate: delegate, stopDelegating: stopDelegating });
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment