1

我有一个 div

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

现在,使用事件委托和冒泡的概念,我想拦截来自 myDiv、myLink 和 anotherDiv 中的任何一个的点击。

根据最佳实践,这可以通过在文档本身上监听全局点击(因此称为“委托”)来完成

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

请参阅上面的警报问题。我的印象是点击会冒泡。它在某种程度上确实如此,因为该文档实际上收到了我的点击并开始委派。但是点击 myLink 和 anotherDiv 的冒泡机制似乎不起作用,因为 if 语句没有启动。

或者是这样的:只点击气泡一步,从点击的 src 元素到分配的委托对象(在本例中为文档)?如果是这种情况,那么我需要像这样处理委托:

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

但是这种方式违背了委托的目的,因为我现在必须有很多“myDiv”处理程序,可能还有其他......只有一个“文档”事件委托对象非常容易。

任何人都知道这是如何工作的?

4

5 回答 5

2

您应该使用来自 JQuery 的实时事件(从 1.3 开始),它使用事件委托:

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

所以你的代码将是:

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

 });

这样,您就拥有了事件委托的所有好处(更快,一个事件侦听器等),而没有痛苦;-)

于 2009-11-18T11:39:38.007 回答
0

Event.target 始终是触发事件的元素,因此当您单击“myLink”或“anotherDiv”时,您使用 $(e.target); 存储对这些对象的引用;因此,您实际上所做的是: $('.myLink').is('.myDiv') 返回 false,这就是不执行 alert() 的原因。

如果你想以这种方式使用事件委托,你应该检查 event.target 是元素还是它的任何子元素,使用 jQuery 可以这样做:

$(e.target).is('.myDiv, .myDiv *')
于 2009-11-18T11:42:46.270 回答
0

对我来说似乎工作正常。在这里试试:http: //jsbin.com/uwari

于 2009-11-18T11:43:12.043 回答
0

事件目标不会改变。您需要反映 jquery live 所做的事情并实际检查 $eventElem.closest('.myDiv') 是否提供匹配项。

尝试:

$(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;
});
于 2009-11-18T11:43:31.567 回答
0

看看这个:一页中的一键式处理程序

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;
   }
});
于 2014-01-03T06:12:55.053 回答