2011-06-02 91 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. 
});