I've been writing my own event delegation handling for a long time,
but today I thought I'd look at how the delegate plugin does it. Not
very complicated, as I found out!

It doesn't do one thing that I needed today, however. It doesn't check
for matches against the whole bubble chain - just against the actual
event target.

For example, I load a table into a container via ajax, and I want to
delegate the handling of table row clicks to the container so it still
works after ajax reloads. The table source may look like:

<table>
<tbody>
   <tr class="user">
      <td>Matt</td>
      <td>Kruse</td>
   </tr>
</tbody>
</table>

I want to fire a function when the user clicks on "tr.user". But when
they actually click, the target is one of the td's, not the tr.

I modified the delegate plugin to start at the target element and then
bubble up through each parent element to check the selectors, just as
the original event bubbling did. This way I can check for selector
matches anywhere up the chain, not just on the target.

I also changed it so I could use syntax like this:

$('#container').delegate( 'click' , { '.selector1':func1,
'.selector2':func2 } );
or:
$('#container').delegate( 'click' , '.selector1', func1 );

Because of the simulated bubbling, I wouldn't use this for any events
that fire rapidly. But in my tests of handling clicks (probably 95% of
all event delegation I do) it works very quickly.

Here is my modified code. Any thoughts?

;(function($) {
        $.extend($.fn, {
                delegate: function(type, handlers, handler) {
                        if (typeof handlers!='object') {
                                // A single selector/handler has been passed in
                                handlers = {handlers:handler};
                        }
                        var selector;
                        return this.bind(type, function(e) {
                                var $o = $(e.target);
                                while($o&&$o[0]&&$o[0]!=this) {
                                        for (selector in handlers) {
                                                if ($o.is(selector)) {
                                                        return 
handlers[selector].apply($o,[$o,e]);
                                                }
                                        }
                                        $o = $o.parent();
                                }
                        });
                }
        })
})(jQuery);


Matt Kruse

Reply via email to