2012-05-06 34 views
11

Setup:jQuery chức năng được gọi hai lần cho mỗi nhấp chuột

Tôi đã viết một hàm jQuery để cập nhật các tế bào bảng table_2, khi một hàng trong table_1 được nhấp. Dưới đây là những gì tôi đã viết:

<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> 

Vấn đề:

Khi tôi bước qua chức năng này sử dụng Firebug, tôi có thể xem dữ liệu di động trong myTable_2 đã được thay đổi. NHƯNG, cho mỗi nhấp chuột, chức năng được thực hiện hai lần. Tôi có thể thấy hộp cảnh báo xuất hiện hai lần cho mỗi lần nhấp.

Ai đó có thể cho tôi biết tại sao điều này xảy ra? Và làm thế nào để tránh điều này?

Trả lời

11

Hoặc trong các cách sau:

  1. Hàng nhấp là bên trong hàng khác (hai hàng được nhấp vào). (example)
  2. Mã bạn đã hiển thị được thực thi hai lần (example).

Để giải quyết vấn đề này, hãy làm cho bộ chọn của bạn cụ thể hơn. Nếu bạn đang sử dụng jQuery 1.7+, sử dụng .on thay vì live: http://jsfiddle.net/6UmpY/3/

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

Lưu ý: Sử dụng .on thay vì live đã không giải quyết vấn đề.
Sử dụng công cụ chọn cụ thể hơn đã làm khắc phục sự cố.
Nếu bạn yêu live, sau đây cũng sẽ làm việc: http://jsfiddle.net/6UmpY/4/

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

giả table_1 là id của bảng đầu tiên.

$("#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); 
     }); 

LƯU Ý:live() đã bị phản đối, vì vậy viết như trên. bạn thực thi mã hai lần vì bộ chọn tr thuộc về cả hai bảng và liên kết sự kiện hai lần.

Bạn cũng có thể sử dụng 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

Cảm ơn bạn đã trả lời. Vì vậy, bạn có nghĩa là bằng cách sử dụng 'on' hoặc 'delegate' sẽ giải quyết vấn đề của chức năng nhận được gọi là hai lần? – Bhushan

+0

@Learner không có 'on()' được sử dụng để liên kết sự kiện từ jquery 1.7+ và sự kiện cháy hai lần sẽ giải quyết bằng cách sử dụng '# table_1', vì nó sẽ chỉ chọn' tr' thuộc bảng đầu tiên – thecodeparadox

+0

nhờ thecodeparadox. – Bhushan

12

chỉ đơn giản là tránh việc tuyên truyền của nhấp chuột

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

     ... 

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

Có bất kỳ hậu quả tiêu cực tiềm ẩn nào khi thực hiện việc này không? –

+1

Điều này dừng bất cứ điều gì khác nghe sự kiện trên phần tử nhận sự kiện. Các sự kiện được gọi theo thứ tự chúng được thêm vào và chỉ các sự kiện được thêm sau khi sự kiện này sẽ bị ngăn chặn. – neopickaze

0

Đó là vì $ ("tr") sống (nghe tiếng 'click', function.() {}); ^^^^^ có 2 giá trị trong html. Để đảm bảo .live() hoặc .delegate() được thực thi một lần, công cụ chọn trong $ (selector) .delegate() tốt hơn là "$ (table [name = users])" thay vì $ ('td') hoặc $ ('tr')

0

Một số thành phần có thể có cùng thuộc tính (tên lớp, tên thẻ vv) mà bạn có thể bỏ qua. Điều này có thể gây ra xung đột như vậy. Trong ví dụ bên dưới phần tử "tr" được sử dụng làm bộ chọn cho cảnh báo, nhưng tập lệnh có hai phần tử "tr" lồng nhau chứa mục tiêu "văn bản".Do đó, với một cú nhấp chuột, bạn sẽ nhận được cảnh báo được kích hoạt cho mỗi phần tử (từ trong ra ngoài) một cách riêng biệt. Điều này được gọi là bubbling. Bạn chỉ cần sử dụng stopPropogation() để dừng số 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/

Các vấn đề liên quan