【转】Event Delegation Made Easy

From http://danwebb.net/2008/2/8/event-delegation-made-easy-in-jquery

I’m having a lot of fun poking around jQuery at the moment and came up with a cool little thing that’s going into Low Pro for jQuery but is a nice stand-alone little snippet for implementing event delegation. Since the Christian and the guys at YUI started talking about it event delegation has gone from being something that I’d use occasionally to the way I do nearly all my event handling. If you aren’t familiar with the technique go and click that previous link and read Christian’s article now – it’s important.

In most instances I end up writing a lot of event handlers that look like this:

$('#thing').click(function(e) { var target = $(e.target); if (target.hasClass('quit') return doQuitStuff(); if (target.hasClass('edit') return doEditStuff(); // and so on...
});

Obviously, writing a lot of the same kind of code is a warning sign that something needs refactoring but I’ve never come up with a nice way to abstract this. But with a little bit of functional magic I’ve just found with something I really like. Here’s what I came up with:

jQuery.delegate = function(rules) { return function(e) { var target = $(e.target); for (var selector in rules) if (target.is(selector)) return rules[selector].apply(this, $.makeArray(arguments)); } }

Using it is simple:

$('#thing').click($.delegate({ '.quit': function() { /* do quit stuff */ }, '.edit': function() { /* do edit stuff */ } }));

The function simple runs through the rules checking if the element that fired the event belongs to that selector then calls the corresponding handler passing the original event object through. The great thing about it is that you can use it in Low Pro behavior classes:

DateSelector = $.klass({ onclick: $.delegate({ '.close': function() { this.close() }, '.day': function(e) { this.selectDate(e.target) } }), selectDate: function(dayElement) { // code ...
}, close: function() { // code ...
} });

I’m not sure of the performance implications of using is() so heavily but some form of caching could be added if it was a problem. Still, it’s a really nice little bit of syntactic sugar that’s going into Low Pro for jQuery and I’ll be using it a lot.

UPDATE: I should have added that there’s a version of this in Low Pro for Prototype. In case you want to use it on its own:

Event.delegate = function(rules) { return function(e) { var element = $(e.element()); for (var selector in rules) if (element.match(selector)) return rules[selector].apply(this, $A(arguments)); } }

Meanwhile, you might want to take a look at the patch by Peter Michaux.

posted @ 2012-03-01 10:01  JulianHere  阅读(133)  评论(0编辑  收藏  举报