Created
February 18, 2009 21:49
-
-
Save RStankov/66568 to your computer and use it in GitHub Desktop.
This file contains 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
(function(){ | |
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)){ | |
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
:)
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 ( http://github.com/RStankov/controldepo-3-widgets/blob/master/src/behaviors.js )
It has event delegation build in ( soon I will update it to use Event.on ). With it you could something like: