开发者

Simple click event delegation not working

I have a div

<div class="myDiv">
  <a href="#" class="myL开发者_开发技巧ink">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?


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 ;-)


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;
});


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 *')


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


Check this out: One click handler in one page

var page = document.getElementById("contentWrapper");
page.addEventListener("click", function (e) {
   var target, clickTarget, propagationFlag;      
   target = e.target || e.srcElement;
   while (target !== page) {
      clickTarget = target.getAttribute("data-clickTarget");
      if (clickTarget) {
          clickHandler[clickTarget](e);
          propagationFlag = target.getAttribute("data-propagationFlag");
      }
      if (propagationFlag === "true") {
          break;
      }
      target = target.parentNode;
   }
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜