2014-03-06 34 views
5

我有兩個共同工作的jQuery函數,一個取決於一個類,另一個取消類。我刪除類後JQuery選擇器仍然工作?

一旦它被刪除,我希望功能停止工作,但它繼續?

怎麼回事?

以下是fiddle,請親自嘗試一下。

<div class="container disabled"> 
    <a href="www.google.com">Go to Google</a> 
</div> 
<label> 
    <input type="checkbox" />Enable link</label> 

的JS

$('.disabled > a').click(function (e) { 
    e.preventDefault(); 
    e.stopPropagation(); 
    alert('should stop working'); 
}); 

$('input[type=checkbox]').change(function() { 
    $('.container').removeClass('disabled'); 
}); 
+0

即使你已經刪除了類,動作已經被綁定到元素中。它不會自動解除綁定。 –

回答

15

它看起來像你想用委託的事件處理程序,而不是靜態的事件處理程序是。讓我解釋。

當你運行像這樣的一行代碼:

$('.disabled > a').click(function (e) { 

這對安裝在那個時刻選擇匹配的任何對象的事件處理程序。那些事件處理程序將永久存在。他們不再看任何元素有什麼類。因此,在安裝靜態事件處理程序後更改類不影響哪些元素具有事件處理程序。

如果您想要dynanamic行爲哪些元素響應事件取決於哪些類在任何給定時刻出現,那麼您需要使用委託事件處理。

通過委託事件處理,您可以將事件「永久」附加到父級,然後父級會評估每次事件觸發時事件發起的孩子是否與選擇匹配。如果孩子不再匹配select,那麼事件處理程序將不會被觸發。如果是這樣,那麼它會和你可以添加/刪除一個類,使其改變行爲。

委派的事件處理程序的一般形式是這樣的:

$("#staticParent").on("click", ".childSelector", fn); 

你最好要選擇一個父是接近孩子越好,但不是動態的本身。在您的具體的例子,你不顯示比身體其他物體父母,所以你可以使用這個:

$(document.body).on("click", ".disabled > a", function() { 
    e.preventDefault(); 
    e.stopPropagation(); 
    alert('should stop working');  
}); 

當您添加刪除disabled類這個代碼就動態響應。如果disabled類存在,則事件處理程序將觸發。如果它不存在,則事件處理程序不會觸發。

工作演示:http://jsfiddle.net/jfriend00/pZeSA/

上委派事件處理其他參考資料:

jQuery .live() vs .on() method for adding a click event after loading dynamic html

jQuery .on does not work but .live does

Should all jquery events be bound to $(document)?

JQuery Event Handlers - What's the "Best" method

jQuery selector doesn't update after dynamically adding new elements

+0

我剛發佈這個問題後才發現這個,但是非常詳細的補充。 – shenku

+0

真棒回答。謝謝。 –

+0

這是我一直使用Google搜索一個小時。非常感謝!! –

1

當選擇器運行時,它將獲取包括有問題的元素列表並添加一個單擊事件處理程序。

然後你刪除類 - 所以任何後續的jQuery選擇器不會得到你的元素 - 但你已經附加了事件,所以它仍然會觸發。

您使用的選擇器在您聲明的行上運行 - 發生點擊時不會延遲初始化。

3

在事件處理程序綁定後更改類絕對沒有效果,因爲事件處理程序是而不是突然解除綁定,它仍然綁定到相同的元素。

你必須檢查類的事件處理程序

$('.container > a').click(function (e) { 
    if ($(this).closest('.container').hasClass('disabled')) { 
     e.preventDefault(); 
     e.stopPropagation(); 
    } 
}); 

$('input[type=checkbox]').change(function() { 
    $('.container').toggleClass('disabled', !this.checked); 
}); 

FIDDLE

+0

爲什麼不直接使用委託事件處理程序,以便事件處理程序本身對添加/刪除的類進行動態響應? – jfriend00

+0

@ jfriend00 - 這是一種選擇,在這種情況下,我只是檢查班級的存在,但這只是我,無論哪種方式都很好。 – adeneo

+0

@ jfriend00 - 這就是委託處理程序所做的事情,它會檢查目標是否具有該類,因此只需自行執行,就可以限制事件處理程序觸發的元素數量,並且我至少會認爲它的效率更高。 – adeneo