jQuery e.target冒泡最佳实践?

3
在我的大量ajax代码中,我经常将"click"事件绑定在body标签上,并根据$(e.target)和$.fn.hasClass()进行操作。然而,当我点击一个带有标签的锚点时,$(e.target)会等于该节点,而不是我想要的父级锚点。
从现在开始,我使用了这个技巧(var $t = $(e.target);):
/** bubbling **/
if($t.get(0).tagName !== "A" && $t.get(0).tagName !== "AREA") {
    $t = $t.parent("a");
   if(empty($t)) return true;
   //else console.log("$t.bubble()", $t);
}

感觉有些不对...您有更好的实现方式吗?


$.fn.live()并不能解决我的问题,因为它仍然会返回作为目标。此外,我正在寻求速度(在基于Atom的触摸设备上运行),而live 显得要慢得多(两倍):http://jsperf.com/bind-vs-click/3


事实上,正如@Guffa所指出的那样,使用$.fn.live()解决了冒泡的问题,因为我不再需要event.target。我猜这里没有其他“正确”的答案(在容器上使用绑定)。

3个回答

2
为什么不使用为您完成此操作的live方法?
$('a.someclass').live('click', function(){
  // do something
});
< p > live 方法绑定到 body 元素并检查事件目标是否匹配选择器。

jQuery: live


我需要最低的开销(在基于Atom的触摸设备上运行),而且实时显示速度要慢得多(两倍):http://jsperf.com/bind-vs-click/3 - Olivier
此外,它并没有解决我的问题:跨越到锚点的span冒泡问题。 - Olivier
如果您使用live方法,则无需使用事件目标,它将根据您用于注册的选择器调用不同的函数。 - Guffa
如果你非常关注速度,那么对 $('a.someclass') 的初始调用可能是昂贵的,并且在使用事件委托时可以避免(如果 jQuery 可以预测此调用仅用于注册选择器,则会跳过查找,但它无法)。如果您使用的是jQuery 1.4.x,可以改用delegate,并使用一个更便宜的选择器开始(例如$(document).delegate('a.someclass', 'click', handler);)。 - eyelidlessness
@Guffa,“委托”显然是正确的选择。我已经使用它了。谢谢。 - Olivier

1

closest 在这里非常有用(虽然其他方法 - livedelegate - 在下面描述):

$t = $t.closest('a');

这个程序从以$t开头的元素开始,向上遍历父元素链,直到找到一个与给定选择器匹配的元素 — 在这种情况下是"a"。

以下是一个基本示例:

HTML:

<a href='#'><span>Outer span <span>inner span <em>em</em></span></span></a>

使用jQuery的JavaScript:

jQuery(function($) {

  $(document).click(function(e) {
    var $t = $(e.target).closest('a');
    $t.css("border", "1px solid black");
    return false;
  });

});​

实时副本

点击链接会在链接周围放置一个边框,无论您是在其中一个元素中还是em元素或其他地方单击。

有点离题,但是最近版本的jQuery通过live(基本上执行您所做的操作,将事件挂钩在主体上,然后查看发生在哪个实际元素上,并应用选择器以匹配元素)和delegate(与live相同,但根据特定元素而不是文档本身进行操作)来处理此问题。


最接近的可能会对这里有用,但不在话题之内(实际上也不需要它),现场直播是另一种较慢的方法,而我更注重速度。 - Olivier

0

我猜你这么做是因为bind在AJAX调用后插入的内容上不起作用。我建议你使用live来附加事件并允许jQuery处理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接