2015-11-06 61 views
0

我剛剛開始玩jQuery,並創建了一個簡單的函數。它工作正常,除了這個事實,它是活躍的並且只是第一次繼續工作。 (該功能本身就像選擇列表)。當您再次單擊它時,它不響應。爲什麼是一次性功能?

$('.selected').click(function(){ 
 
      $(this).removeClass('selected').addClass('selectoption'); 
 
      $('.selectoption').show().click(function(){ 
 
       $(this).removeClass('selectoption').addClass('selected'); 
 
       $('.selectoption').hide(); 
 
      }); 
 
     return true; 
 
    });
.selectoption { 
 
    display: none; 
 
    float: right; 
 
    clear: both; 
 
    margin-top: 3px; 
 
    padding: 5px 10px 5px 10px; 
 
    text-align: right; 
 
    color: #FFFFFF; 
 
    background: #3399FF; 
 
    border: solid #ffcc00 1px; 
 
} 
 
.selected { 
 
    display: block; 
 
    border-bottom: dashed #3399FF 1px; 
 
}
<div style="display: block; position: absolute; top: 32px; right: 220px; border: 0;"> 
 
          <a href="#" class="selected">1</a> 
 
          <a href="#" class="selectoption">2</a> 
 
          <a href="#" class="selectoption">3</a> 
 
          <a href="#" class="selectoption">4</a> 
 
         </div>

+0

http://stackoverflow.com/questions/3731361/click-event-executed-only-the-first-time 的http:// stackoverflow.com/questions/10194728/jquery-click-event-works-only-once 和許多 –

+0

我建議你在瀏覽器中打開調試器,並在每個點擊處理程序中放置一個斷點。我懷疑你會發現兩個點擊處理程序正在運行,並且每個處理程序都執行另一個處理程序的反轉處理,所以你不會看到任何淨變化。 – dsh

回答

2

.click()只綁定到存在於所綁定的事件時DOM節點。您的代碼假定事件綁定到事件本身發生時存在的DOM節點。

該第一行僅將click函數綁定到當前具有'.selected'類的元素 - 因此只有HTML中的第一個錨標記具有綁定到它的單擊事件。調用此事件答:

$('.selected').click(function(){ 
     $(this).removeClass('selected').addClass('selectoption'); 

在單擊該第一錨,你綁定一個新的單擊事件到錨的所有四個(因爲你已經從第一錨刪除「.selected」類,並添加」。 selectoption')。調用此事件B:

 $('.selectoption').show().click(function(){ 
      $(this).removeClass('selectoption').addClass('selected'); 
      $('.selectoption').hide(); 
     }); 
    return true; 
}); 

所以你的錨1第一次點擊後,錨1將觸發事件都A和事件B時,下一個被點擊(一個新的事件結合到同一個元素不會取代現有的事件)。其餘的錨點只會觸發事件B.

您實際上想要的行爲可以通過在父元素上使用.on()來實現 - 這有效地將事件綁定到CSS選擇器而不是特定的DOM節點,以便當用戶單擊父元素時,你的代碼檢查,看看是否被點擊的目標類選擇匹配:

$('.parent') 
 
     .on('click', '.selected', function(evt) { 
 
     $(evt.target).removeClass('selected').addClass('selectoption'); 
 
     }).on('click', '.selectoption', function(evt) { 
 
     $('.selected').removeClass('selected').addClass('selectoption'); 
 
     $(evt.target).removeClass('selectoption').addClass('selected'); 
 
     });
.selected { 
 
    background-color: #F00 
 
} 
 
.selectoption { 
 
    background-color: #0F0 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="parent"> 
 
    <a href="#" class="selected">1</a> 
 
    <a href="#" class="selectoption">2</a> 
 
    <a href="#" class="selectoption">3</a> 
 
    <a href="#" class="selectoption">4</a> 
 
</div>
(我刪除了 hide()show(),改變了CSS規則,使其更容易地看到發生了什麼事情,但除此之外,這表現得像我認爲的那樣。)

所以現在兩個點擊事件綁定到.parent;如果父代中的點擊目標匹配.select,則第一個會觸發,如果點擊目標匹配.selectoption,則第二個會觸發 - 而且與原始代碼不同,類匹配是實時的,因此您可以安全地更改DOM元素上的類,或者綁定事件後添加新元素,並使行爲遵循新的類名。

在 '委託事件' 這裏詳細瞭解了起來:http://api.jquery.com/on/

0

要卸下類,所以它不能再被發現。這是最好的一個額外的類聽添加到點擊

<div style="display: block; position: absolute; top: 32px; right: 220px; border: 0;"> 
    <a href="#" class="option selected">1</a> 
    <a href="#" class="option">2</a> 
    <a href="#" class="option">3</a> 
    <a href="#" class="option">4</a> 
</div> 

然後簡化你的腳本到

$('.option').click(function() { 
    $(".option").removeClass('selected'); // we need to remove all selected classes first ;) 
    $(this).addClass('selected'); 
    return true; 
}); 
+0

我會挑剔一點,對不起。 :)這段代碼有效(除非它不會從被選中的項目中刪除'selected'狀態,這可能是無意中的行爲) - 但這裏給出的原因是不正確的:刪除類不會刪除該事件或使其「不再被發現」。這個原因是因爲你將click事件綁定到所有四個錨點 - 如果在事件之後添加了新的.option錨點,它不會拾取事件(並且類似地,如果刪除選項類,這不會消除事件。) –

+0

但是,在添加新選項定位符的地方無法讀取 –

+0

的確,這只是一個示例,可以幫助解釋綁定發生了什麼。 –