2012-05-06 103 views
11

設置:jQuery函數被調用兩次,每次點擊

我已經寫了一個jQuery函數來更新TABLE_2的表格單元格,單擊在TABLE_1行時。以下是我已經寫了:

<script type="text/javascript"> 
     $("tr").live('click',function() { 
      var host = $(this); 
      alert('A row in table 1 is clicked!'); 

      var count = host.find("td").eq(2).text(); 
      $("#myTable_2 tr:eq(0) td:eq(1)").text(count); 
      $("#myTable_2 tr:eq(1) td:eq(1)").text(5); 
     }); 
    </script> 

問題:

當我使用Firebug步驟,通過這個功能,我可以看到在myTable_2單元格數據正在被改變。但是,對於每次點擊,該功能都會執行兩次。每次點擊都可以看到兩次提醒框。

有人可以告訴我爲什麼會發生這種情況?以及如何避免這種情況?

回答

11

以下任一項:

  1. 被單擊的行是其他行內(兩行點擊)。 (example
  2. 您顯示的代碼被執行兩次(example)。

要解決這個問題,請使您的選擇器更具體。如果你正在使用jQuery 1.7+,使用.on代替livehttp://jsfiddle.net/6UmpY/3/

$(document).on("click", "#myTable_1 > tbody > tr", function() { 
    // This selector will only match direct rows of the myTable_1 table 

注意:使用的.on代替live沒有解決的問題。
使用更具體的選擇器確實解決了這個問題。
如果你愛live,下面也將工作:http://jsfiddle.net/6UmpY/4/

$("#myTable_1 > tbody > tr").live("click", function() { 
3

假設table_1是第一個表的ID。

$("#table_1 tbody").on('click','tr', function() { 
      var host = $(this); 
      alert('A row in table 1 is clicked!'); 

      var count = host.find("td").eq(2).text(); 
      $("#myTable_2 tr:eq(0) td:eq(1)").text(count); 
      $("#myTable_2 tr:eq(1) td:eq(1)").text(5); 
     }); 

注:live()已被棄用,所以寫像上面。你的代碼執行兩次,因爲tr選擇器屬於兩個表,事件綁定兩次。

您還可以使用delegate()

$("#table_1 tbody").delegate("tr", "click", function(){ 
    var host = $(this); 
    alert('A row in table 1 is clicked!'); 
    var count = host.find("td").eq(2).text(); 
    $("#myTable_2 tr:eq(0) td:eq(1)").text(count); 
    $("#myTable_2 tr:eq(1) td:eq(1)").text(5); 
}); 
+0

感謝您的答覆。所以你的意思是使用'on'或'delegate'將解決函數調用兩次的問題? – Bhushan

+0

@Learner no'on()'用於綁定來自jquery 1.7+的事件,並且兩次事件fire將通過使用'#table_1'解決,因爲它只會選擇屬於第一個表 – thecodeparadox

+0

的'tr',感謝codeparadox。 – Bhushan

12

只是簡單的避免點擊

$("tr").live('click',function() { 

     ... 

     $(event.toElement).one('click', function(e){ e.stopImmediatePropagation(); }); 
    }); 
+0

這樣做有沒有任何潛在的負面後果? –

+1

這將阻止任何其他聽元件接收事件的事件。事件按照它們添加的順序被調用,並且只有在這個事件之後添加的事件纔會被阻止。 – neopickaze

0

它的傳播,因爲 $( 「TR」)生活( '點擊' 功能。 (){}); ^^^^^在html中有2個計數。爲確保.live()或.delegate()被執行一次,$(selector).delegate()中的選擇器最好是「$(table [name = users])」而不是$('td')。或$('tr')

0

某些元素可能具有相同的屬性(類名稱,標記名稱等),您可能會忽略。這可能會導致這樣的衝突。在下面的示例中,「tr」元素用作警報的選擇器,但該腳本具有兩個嵌套的「tr」元素,其中包含「text」目標。因此,只需點擊一下,你會得到一個警告射擊每個(從內向外)「TR」元素seperately。這被稱爲bubbling。你可以簡單地使用stopPropogation()停止bubbling

$("tr").live('click',function() { 
    alert('A row in table 1 is clicked!'); 
    event.stopPropogation(); 
}); 

<table> 
    **<tr>** 
    <td>  
     <table id="myTable_1"> 
     **<tr>** 
     <td>Test</td> 
     **</tr>** 
     </table> 
    </td> 
    **</tr>** 
</table> 

http://jsfiddle.net/6UmpY/97/