Ticket #951 (new enhancement)
Event Delegation method for Element
| Reported by: | Devign | Owned by: | |
|---|---|---|---|
| Type: | enhancement | Priority: | major |
| Milestone: | Mootools version 1.2 | Component: | Core |
| Keywords: | Event, Delegation | Cc: |
Description
I wrote a simple function for delegating events to all children of an element.
It gets a string selector or a predicate function that gets current checked child element and returns boolean.
The idea is relying on event bubbling and when event happens on a parent element, the event object still contains the actual element the event was fired from (in .target).
It surly needs some improvements, such as supporting undelegating events, or passing more than one event on same selector (like addEvent and addEvents) and I'll be glad to do these if it gets to mootools base.
Element.implement({
/*
Event delegation - instead of attaching events to new elements, attach to parent and use bubbling to fire children events
Useage:
<ul id="list">
<li>Foo</li>
<li>Bar</li>
<li>Bar</li>
</ul>
$("list").delegateEvent("click","li",function(e) { this==li },false,true);
// or
$("list").delegateEvent("click",function (el) { return Element.get(el,'tag')=="li"; },function(e) { this==li },false,true);
*/
delegateEvent:function (type,selector,fn,preventDefault,stopPropagation) {
var check=$type(selector)=="function" ? selector : function (target) { return Element.match(target,selector) };
return this.addEvent(type,function (e) {
var target=e.target;
while (target!=document.body) {
if (check(target)) {
if (preventDefault) e.preventDefault();
if (stopPropagation) e.stopPropagation();
return fn.apply($(target),[e]);
}
target=target.parentNode;
}
}.bind(this));
}
});