views:

45

answers:

2

Hi there,

I'm trying out jquery as a javascript library over prototype. Now when it comes to event delegation in prototype I can do the following:

  $('wrapper').observe('click', function(event) {
        var foo = Event.findElement(event, '.foo1');
        if (foo) // do something 

        var bar = Event.findElement(event, '.bar1');
        if (bar) // do something else
    });

So this means only one click handler is placed on the document.

I know jquery has live/delegate methods, but it seems you need to provide the selector in the call (unless I'm mistaken?). Is there a similar way to have just one click handler and do something similar? Or is it better to split them up as separate events?

Thanks

+3  A: 

I think it's a bit cleaner to split them up. When you look at the result it's a bit cleaner/easier to maintain. Here's what .delegate() would look like:

$('#wrapper').delegate('.foo1', 'click', function(event) {
  // do something for .foo1 
})).delegate('.bar1', 'click', function(event) {
  // do something for .bar1
});

To answer the question yes you can have a single handler, for example:

$('#wrapper').delegate('.bar1, .foo1', 'click', function(event) {
  if($(this).is('.foo1') // do something for .foo1 
  if($(this).is('.bar1') // do something for .bar1 
});

There are also other approximate methods, e.g. with .click() and $.contains(). But this and other methods are less efficient and a bit harder to maintain, at least to me, you can decide what's best, but I'd personally go with the 2 handlers in this case.

Nick Craver
I'll stick with the separate ones, many thanks!
Rishi
A: 

I'm trying to replicate your example in jQuery (NOTE: As Nick pointed out in the comments, this might not work in all cases as you would like it to. Nick's answer shows a better approach with jQuery's .delegate().):

$('#wrapper')
  .bind(
    'click',
    function(e)
    {
      if($(e.target).is('.foo1'))
      {
        // do something with $(e.target)
      }
      else if($(e.target).is('.bar1'))
      {
        // do something with $(e.target)
      }
    }
  );
Thomas
This isn't quite the same, since a click may have originated in a *child* of those elements, and the target itself won't have the class.
Nick Craver
@Nick Craver: You're right. I've added a note pointing out those limitations.
Thomas