2011-06-02 74 views
4

我遇到了一个我不知道解决方案的问题。jQuery:绑定可以处理其子项事件的单个事件侦听器

假设我有这样的HTML标记(由服务器或只是一个静态文件动态生成):

<ul class="myList"> 
<li><a href="page1.html">Page 1</a></li> 
<li><a href="page2.html">Page 2</a></li> 
<li><a href="page3.html">Page 3</a></li> 
<li><a href="page4.html">Page 4</a></li> 
<li><a href="page5.html">Page 5</a></li> 
<li><a href="page6.html">Page 6</a></li> 
<!-- ... --> 
<li><a href="page1000.html">Page 1000</a></li> 
</ul> 

我要绑定一个click事件处理程序的<一个>标签。通常情况下,我会写出来

$('.myList').find('a').click(function() {}); /* Or something similar */ 

这将在所有的锚标签执行隐迭代click事件绑定到他们每个人。不过,我被告知这是一项昂贵的操作。

我被问到是否有某种方法只附加一个事件监听器(在ul标签上)并使用事件冒泡来确定哪个锚标签被点击。我从来没有遇到过这样的事情,所以我不知道答案。显然,有一个答案。有没有人知道如何在一个元素上放置一个事件监听器,并让它找出哪个子元素被点击了? (我仍然需要使用event.preventDefault()来防止默认的单击事件。)

回答

12

退房delegate() —这正是你所要求的。

$('ul.mylist').delegate('a', 'click', function() { 
    // ... your code ... 
}); 

您可以获得jQuery处理程序的所有好处,而无需对所有这些元素进行绑定。

+0

+1我忘了'delegate()'。 – alex 2011-06-02 00:50:36

4

您可以访问event.target,它将成为启动事件的元素。

$('.myList').click(function(event) { 
    var target = $(event.target); 
}); 

jsFiddle

但是,Pointy's answer似乎更容易使用。

+0

同时,很有必要知道,但我同意你的说法.delegate()更容易使用。 – Stephen 2011-06-02 01:01:07

0

您附加的功能将有一个事件参数,其中包含在event.target中单击的对象。

$(.....).click(function(event){ .... }); 

另一种解决方案,更复杂,更灵活也一样,虽然你不会需要它在这种情况下,是使用.bind方法并指定一个数据对象

$(.....).bind('click', {whateverproperty: whatevervalue}, function(event){ ... }); 

在这种情况下, ,您可以达到event.data.whateverproperty,从而检索值whatevervalue,使您可以做出更复杂的决策。

1

如果您使用的是jQuery> = 1.7的版本,则.on()方法将取代.delegate()。在这两个jQuery的2.x1.11.delegate()简单地调用.on()

delegate: function(selector, types, data, fn) { 
     return this.on(types, selector, data, fn); 
} 

要使用它,在这种情况下:

$(".myList li a").on("click", function(e) { 
    //Code here, and you can use e.preventDefault(); to avoid the default event. 
});