views:

98

answers:

4

I have a div

<div class="myDiv">
  <a href="#" class="myLink">somelink</a>
  <div class="anotherDiv">somediv</div>
</div>

Now, using event delegation and the concept of bubbling I would like to intercept clicks from any of myDiv, myLink and anotherDiv.

According to best practices this could be done by listening for clicks globally (hence the term 'delegation') on the document itself

$(document).click(function(e) {
  var $eventElem = $(e.target);
  var bStopDefaultClickAction = false;

  if ($eventElem.is('.myDiv'))
  {
    alert('Never alerts when clicking on myLink or anotherDiv, why????');
    bStopDefaultClickAction = true;
  }

  return bStopDefaultClickAction;
});

See my alert question above. I was under the impression that clicks bubble. And it somewhat does because the document actually receives my click and starts delegating. But the bubbling mechanism for clicks on myLink and anotherDiv doesn't seem to work as the if-statement doesn't kick in.

Or is it like this: clicks only bubble one step, from the clicked src element to the assigned delegation object (in this case the document)? If that's the case, then I need to handle the delegation like this:

$('.myDiv').click(function(e) {
  //...as before
});

But this kind of defeates the purpose of delegation as I now must have lots of 'myDiv' handlers and possibly others... it's dead easy to just have one 'document' event delegation object.

Anyone knows how this works?

+1  A: 

You should use live event from JQuery (since 1.3), it use event delegation :

http://docs.jquery.com/Events/live

So you code will be :

 $(".myDiv").live("click", function(){
      alert('Alert when clicking on  myLink elements. Event delegation powaa !');

 });

With that, you have all the benefices of event delegation (faster, one event listener etc..), without the pain ;-)

Samuel Michelot
But I want it on the document so that I can handle ALL my clicks in one place. Is it true that live uses closest() internally? If so, then why? Why isn't the concept of bubbling taking care of this?
Tommy
live comes with some performance penalties. Especially when you start adding multiple live delegates. native delegation always better - until the next jq version 1.4 where you can pass in the context to listen on rather than it being the document every time
redsquare
THAT sounds great.
Tommy
A: 

Event.target is always the element that triggered the event, so when you click on 'myLink' or 'anotherDiv' you store a reference to these objects using $(e.target); So what you do in effect is: $('.myLink').is('.myDiv') which returns false, and that's why the alert() is not executed.

If you want to use event delegation this way, you should check wheter event.target is the element or any of its children, using jQuery it could be done like this:

$(e.target).is('.myDiv, .myDiv *')
pawel
Of course, but the click on myDiv should bubble calling the event delegation repeatedly. Eventually eventElem will be (or should be) myDiv.
Tommy
event.target does not change during capturing and bubbling phases - it's always a reference to the element that triggered the event. AFAIK there's no other way to find out if an event was triggered by a child of given element other than traverse up the DOM tree, or using some library functions.
pawel
A: 

Seems to work fine to me. Try it here: http://jsbin.com/uwari

Justin Johnson
It works, but the way it works is the exact problem OP wants to solve.
pawel
Precisely. I want to take advantage of the full power of event delegation and bubbling, but it seems it's not possible?
Tommy
A: 

The event target will not change. You need to mirror what jquery live does and actually check if $eventElem.closest('. myDiv') provides a match.

Try:

$(document).click(function(e) {
  var $eventElem = $(e.target);
  var bStopDefaultClickAction = false;

  if ( $eventElem.closest('.myDiv').length )
  {
    alert('Never alerts when clicking on myLink or anotherDiv, why????');
    bStopDefaultClickAction = true;
  }

  return bStopDefaultClickAction;
});
redsquare
But what happened to event bubbling? Why look for myDiv when the bubbling mechanism should fix this? Or am I completely wrong here? The power of bubbling is the mechanism of event delegation. Otherwise the document wouldn't have received the click on myDiv in the first place.
Tommy
Well it does not invoke a click event for each parent element. Remember your listening on the top most bubbled event.
redsquare
You're right, thx for sorting this out!
Tommy
glad it helped Tommy
redsquare