2012-02-28 101 views
9

我有在執行以下代碼一些問題:沒有選擇,在()點擊事件

var i = 1; 
$('.hello:not(.selected)').on('click',function(){ 
    $(this).addClass('selected');  
    console.log(i++); 
}); 

的問題是,此代碼應觸發僅一次選擇的類增加了之後,卻是執行很多次,我只想讓變量不增加。換句話說,我想做好以下(這工作,但我不希望使用實時功能,因爲它已經過時):

$('.hello:not(.selected)').live('click', function() { 
    $('.hello').removeClass('selected'); 
    $(this).addClass('selected'); 
... 
}); 

非常感謝事先您的答覆, ķ

+0

請稍微解釋更詳細的是什麼預期的行爲。你想用這個做什麼? – kapa 2012-02-28 08:16:40

+0

我想你忘了一些額外的代碼。請解釋 – 2012-02-28 08:18:25

+0

也有使用[.one()](http://api.jquery.com/one/)的選項 – rkw 2012-02-28 09:17:04

回答

16

您的代碼走的是一套組件,目前滿足這個條件:

$('.hello:not(.selected)') 

,並建立該事件處理程序爲所有永恆

.on('click',function(){ 
    $(this).addClass('selected'); 
    $(this).css({opacity : 0.5});  
    console.log(i++); 
}); 

特別重要的是事實上,一旦處理程序在元素上設置,即使稍後該元素不再滿足條件,它也將繼續處於活動狀態(在這種情況下,通過獲得selected類)。

有幾種方法可以實現所需的行爲。其中之一是動態檢查的「過濾器」的情況仍然是事件處理中認爲:

$('.hello').on('click',function(){ 
    if($(this).hasClass('selected')) { 
     return; 
    } 
    $(this).addClass('selected'); 
    $(this).css({opacity : 0.5});  
    console.log(i++); 
}); 

另一個辦法是委託事件 - 在這種情況下,父元素將一個通知事件它的後代,它會動態的支票,說決定觸發事件處理程序(代碼距離Ben Lee的回答無恥地粘貼)之前後代滿足篩選條件:

$('body').on('click', '.hello:not(.selected)', function() { 
    $(this).addClass('selected'); 
    $(this).css({opacity : 0.5});  
    console.log(i++); 
}); 
+0

我明白你的意思是所有的永恆,只是想知道這是如何工作的:$('。tab:not(.active)')。live('click',function (){,這是因爲live isnt它,但它並沒有爲所有永恆設置這個事件處理程序,抱歉,但是我有點困惑......但是非常感謝soo ......因爲它起作用! – MariaZ 2012-02-28 08:51:07

+0

@ThePrincessKarina:是的,'live'委託事件並最終動態檢查,這就是它如何將「處理程序」附加到當你調用'live'時不存在的元素上 – Jon 2012-02-28 09:16:53

+0

oooow !!! ok !,非常感謝 – MariaZ 2012-02-28 09:20:27

7

問題是事件處理程序不會因爲您更改類而被刪除。你將這些事件附加到元素上,並且他們永遠留在那裏。

要解決這個問題,你可以只測試每個事件的處理「中選擇」類:

$('.hello:not(.selected)').on('click',function(){ 
    if ($(this).hasClass('selected')) { 
     $(this).addClass('selected'); 
     $(this).css({opacity : 0.5});  
     console.log(i++); 
    } 
}); 

但對於效率和簡單的代碼,你應該委託這樣的:

$('body').on('click', '.hello:not(.selected)', function() { 
    var $self = $(this); 
    $self.addClass('selected'); 
    $self.css({opacity : 0.5});  
    console.log(i++); 
}); 

我使用「body」作爲元素來附加這個委派,但是您應該使用樹中較低的東西,比如「.hello」元素的父元素或祖父元素。這隻附加一個事件處理程序,並依靠冒泡來測試每個元素實時更改時的選定狀態。

另請注意,我緩存了var $self = $(this);這也是爲了提高效率,所以你最終不會因爲jQuery的擴展而超出你的需要。

+0

非常好用它的工作原理...非常感謝您的建議,使我的代碼更高效。我試圖複製「$('。tab:not(.active)')。live('click',function(){」,但使用「on」,我想我不會非常喜歡好了,但這澄清... THANKs! – MariaZ 2012-02-28 08:45:11