2010-06-27 40 views
5

thể ai đó cho tôi biết tại sao mã này:jQuery, nhấp vào sự kiện, quá nhiều đệ quy

$('#places-view > tbody').find('td').click(function(evt) { 
    var td = $(this), 
     input = td.find('input'); 
     console.log('click'); 
     console.log(input.attr('disabled'), 'disabled'); 
     if (! input.attr('disabled')) { 
      input.trigger('click'); 
      console.log('inner click'); 
     } 
}) 

ném quá nhiều lỗi đệ quy ...

Trân

Trả lời

1

Khi bạn kích hoạt các "click" , nó không thực sự là một vòng gửi sự kiện riêng biệt — jQuery sẽ chạy các trình xử lý ngay tại đó và sau đó. Vì số <input> của bạn là bên trong<td> của bạn, sự kiện sẽ tự bong bóng ra chính nó là <td>, nơi nó sẽ chạy lại vào trình xử lý đó.

Cũng lưu ý rằng dòng này ở đây:

console.log(input.attr('disabled'), 'disabled'); 

là có lẽ không phải những gì bạn muốn - Tôi nghĩ rằng tôi sẽ luôn luôn đăng nhập từ "tàn tật". Có lẽ bạn có nghĩa là

console.log(input.attr('disabled') + ' disabled'); 
+0

Tôi đang sử dụng bảng điều khiển firebug, vì vậy trong trường hợp của tôi, tất cả đều hoạt động như mong đợi. – Marek

6

Để ngăn chặn sự kiện bọt, đặt event.stopPropagation() trong handler cho sự kiện click input yếu tố của bạn.

$('#places-view input').click(function(event) { 

     // This will prevent the click event from bubbling up and firing 
     // the click event on your <td> 
    event.stopPropagation(); 

     // run the rest of your click code 
}); 

http://api.jquery.com/event.stopPropagation/


EDIT: Như @Pointy ghi chú khác, nó có thể là mục đích của bạn để có xử lý tương tự xử lý cả hai sự kiện, hoặc ít nhất là có xử lý td vẫn bắn khi bạn bấm vào số input.

Nếu đó là trường hợp, bạn sẽ chỉ cần phải kiểm tra để xem nếu xử lý td đã bị sa thải bởi một nhấp chuột vào input, và nếu như vậy, ngăn chặn sự input.trigger("click") từ chạy:

$('#places-view > tbody').find('td').click(function(evt) { 
    var td = $(this), 
     input = td.find('input'); 
     console.log('click'); 
     console.log(input.attr('disabled'), 'disabled'); 
     if (! input.attr('disabled')) { 
       // If the target of the click was not the input, 
       // then trigger the click on the input 
      if(input.not(evt.target).length) { 
       input.trigger('click'); 
       console.log('inner click'); 
      } 
     } 
}); 

Một cách khác để thực hiện thử nghiệm sẽ là:

if(input[0] != evt.target) {... 

Cả hai cách tiếp cận này giả định rằng chỉ có một input. Nếu đó không phải là trường hợp, thì bạn sẽ cần phải cung cấp cho đầu vào một định danh để cho phép thử nghiệm cụ thể hơn.

+0

Điều này đúng, nhưng tôi phải tự hỏi liệu đó có phải là một ý tưởng hay không. Nếu anh ta thực sự muốn xử lý "click" ở cấp độ '', có thể sẽ xấu khi hủy bỏ bong bóng tại '' bởi vì điều đó sẽ làm giảm các nhấp chuột vào ''. Tất nhiên nó phụ thuộc vào những gì khác là trong tế bào bảng. – Pointy

+0

@Pointy - Bạn nói đúng. Giả định của tôi là nhấp chuột cho 'td' xảy ra ở đâu đó trong' td', và như vậy, trình xử lý sẽ tách biệt. Nếu đó không phải là trường hợp, thì OP có lẽ sẽ cần phải kiểm tra 'evt.target' trong trình xử lý' td' để xem liệu nhấp chuột có nằm trong 'đầu vào' hay không, và nếu vậy, bỏ qua kích hoạt' click() 'trên 'đầu vào'. – user113716

+0

Câu trả lời hay, +1 – Mark

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