(Updated 8/13/2008)
View Source (commented)
Source (compressed)
// JavaScript on page:
var myrules = {
'.even': function() { alert('fired ".even" callback') },
'#content .odd': function() { alert('fired "#frame.odd" callback') },
'body #frame div .steven': function() { alert('fired "body #frame div .steven" callback') }
};
// delegate clicks within #frame according to rules
$('frame').delegate('click', myrules);
// Element#delegate:
// fire callbacks for all rules that match any #frame child element when clicked
$('frame').delegate('click', myrules);
// fire countWords when any textarea inside #myform is blurred
$('myform').delegate('blur', 'textarea', countWords);
// fire validateDate when a key is pressed from within inputs with class date
document.delegate('keydown', 'input.date', validateDate);
// Element#stopDelegating:
// remove all rules in myrules attached to #frame
$('frame').stopDelegating('click', myrules);
// remove .even rule attached to #frame
$('frame').stopDelegating('click', '.even');
// remove all blur rules attached to myform
$('myform').stopDelegating('blur');
// remove all rules attached to any element
Event.stopDelegating();
If you don't need the ability to remove delegated observers, delegation looks like the following:
Element.addMethods({
delegate: function(element, selector, eventName, observer) {
// observe parent container
return $(element).observe(eventName, function(event) {
// check if target element (e.g. element that was clicked or moused over)
// matches given selector
if ($$(selector).indexOf(event.target) > -1) {
// if it matches, fire the observer (in the scope of the target element)
return observer.apply(event.target, $A(arguments));
}
});
}
});
$('frame').delegate('#frame p.even', 'click', function() {
alert('delegated!');
});