Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
function delegateHandler(e){
((this.retrieve('prototype_delegates') || $H()).get(e.eventName || e.type) || []).each(function(pair){
if (element = e.findElement(pair.key)){
pair.value.invoke('call', element, e, element);
function delegate(element, selector, event, handler){
element = $(element);
var store = Element.retrieve(element, 'prototype_delegates');
if (Object.isUndefined(store)){, '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){
Event.stopObserving(element, event, delegateHandler);
function clearSelector(element, store, selector, event, estore){
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;
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);
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 });

This comment has been minimized.

Copy link

@metaskills metaskills commented Apr 15, 2010

I just saw this link from my "Unobtrusive JS In Rails 3 With Prototype": article. Really clean stuff and delegation is something I have to get better at, especially when adding/removing elements. BTW, I just noticed that Element.on in the new 1.7 RC of prototype. Cheers!


This comment has been minimized.

Copy link
Owner Author

@RStankov RStankov commented Apr 15, 2010


Yes 1.7 will have Event.on, but before there wasn't such method available. If you are interested you can check my CD3.Behaviors ( )
It has event delegation build in ( soon I will update it to use Event.on ). With it you could something like:

    'body:click': {
        'a[data-method=delete]': MyJsObject.linkToDelete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.