2009-03-12 30 views
16

Tôi đang cố gắng tạo biểu mẫu với một số hành vi động. Cụ thể, tôi có đầu vào của tôi trong divs, và tôi muốn làm cho nó như vậy khi người dùng nhấp vào bất cứ nơi nào trong div, đầu vào được chọn. Tôi đã sử dụng JQuery 1.2.6 và mọi thứ hoạt động tốt.Lỗi "đệ quy quá nhiều" trong JQuery 1.3.2

Tuy nhiên, tôi đã nâng cấp lên JQuery 1.3.2 và tôi đang nhận được một số hành vi lạ. Khi tôi nhấp vào bất kỳ đầu vào nào, tôi sẽ nhận được độ trễ trước khi được chọn. Bảng điều khiển lỗi Firefox của tôi mang lại cho tôi một số lỗi "quá nhiều đệ quy", từ bên trong thư viện JQuery. Tôi đã thử các trang trong Internet Explorer 7 và có một lỗi nói rằng "đối tượng không hỗ trợ tài sản hoặc phương pháp này".

Tôi có làm điều gì sai, hoặc đây có phải là lỗi trong JQuery không? Có ai biết cách khắc phục hành vi này, mà không quay trở lại phiên bản cũ không? Tôi đang sử dụng Firefox 3.0.7 trong trường hợp có vấn đề. Dưới đây là một ví dụ đơn giản tôi đã thực hiện để minh họa cho vấn đề:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html><head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>quiz test</title> 
<script type="text/javascript" src="jquery-1.3.2.min.js"></script> 
</head> 
<body> 
<div class='question'>Favorite soda? 
    <div><input type='radio' name='q' value='A' id='a'><label for='a'>Coke</label></div> 
    <div><input type='radio' name='q' value='B' id='b'><label for='b'>Pepsi</label></div> 
    </div> 
<script type="text/javascript"> 
$(function() { 
    $(".question div").click(function() { 
     $(this).children("input").click(); 
    }); 
}); 
</script> 
</body></html> 

Trả lời

0

Cảm ơn tất cả các bạn. Tôi đã thử ý tưởng của grillix về việc thiết lập thuộc tính được kiểm tra, mặc dù tôi đã phải sửa cú pháp một chút. Đây là những gì tôi đã làm:

$(this).children("input").attr("checked", true); 

Nó hoạt động, nhưng tôi vẫn tò mò là tại sao cách trước đó của tôi ngừng hoạt động với JQuery 1.3.2. Tôi biết về những thay đổi trong hành vi bong bóng của sự kiện, nhưng tại sao tôi không thể khắc phục điều đó bằng cách gọi "event.stopPropagation()" hoặc "return false" trong cuộc gọi lại của tôi?

+0

@ mikez302: khi bạn gọi stopPropagation(), sự kiện đã sôi sục lên đến div; bạn phải thêm một trình xử lý onclick vào nút và nhãn và dừng việc truyền bá ở đó; Ngoài ra, truy xuất sai là tương đương với preventDefault(), không stopPropagation() – Christoph

+0

ps: giải pháp của bạn hoạt động với các nút radio, nhưng sẽ thất bại cho các hộp kiểm – Christoph

+0

Cảm ơn bạn. Hành vi mới này hơi kỳ lạ, nhưng bây giờ tôi đã quen với nó. –

7
$(function() { 
    $(".question div").click(function() { 
     var radio = $(this).children("input")[0]; 
     radio.checked = !radio.checked; 
    }); 
}); 
+0

Cảm ơn phản hồi nhanh. Tôi đã thử bằng cách sử dụng focus() và tôi không nhận được lỗi, nhưng việc nhấp vào div không còn chọn đầu vào giống như nó với click(). –

+0

Ý của bạn là gì? Có gì khác biệt? –

+0

Xin lỗi, tôi không nhận thấy chúng ở đâu có nút radio. –

6

ya, nhấp vào sự kiện bong bóng lên ... vì vậy khi bạn nâng $(this).children("input").click(), bạn đang nâng $(".question div").click() một lần nữa, và như vậy.

+0

Tôi nghĩ rằng vấn đề phải làm với hành vi sủi bọt mới. Tuy nhiên, tôi đã cố gắng gọi event.stopPropagation() trong trình xử lý của tôi và tôi đã có cùng một vấn đề. Tôi cũng đã thử trả về false và tôi vẫn gặp vấn đề. –

+1

Bao gồm mã nội tuyến xung quanh các dấu gạch chéo ngược hoặc '' trong tương lai. Tôi đã sửa nó. – nyuszika7h

+0

oh, ok .. cảm ơn bạn :) – grilix

4

Tại sao bạn cần thực hiện việc này nếu bạn đang sử dụng <label for="">? Nhấp vào nhãn sẽ kích hoạt điều khiển vô tuyến.

[Edit:] Theo dõi trên nhận xét của bạn, bạn có thể làm theo cách này:

Tận dụng hiển thị nhãn như là một yếu tố ngăn chặn, áp dụng tất cả các phong cách bạn đã sử dụng cho div gói lĩnh vực này.

.question label { display:block } 

và sau đó sử dụng bố cục này. Bạn có thể thoát khỏi nếu các div quá.

<label><input type="radio">Coke</label> 
<label><input type="radio">Pepsi</label> 
+0

Tôi thực sự sử dụng điều này như một phần của bố cục phức tạp hơn. Các nhãn không hoàn toàn mất toàn bộ div, tôi không thể làm điều đó với nhãn một mình, và tôi muốn đầu vào được chọn nếu người dùng nhấp vào bất cứ nơi nào trong div. –

+0

đó là giải pháp tốt hơn. – grilix

+0

Tôi đã cố gắng làm cho khối nhãn, nhưng nó đã không đi lên khá theo cách tôi muốn. Tôi có lẽ có thể sửa chữa nó nếu tôi đánh lừa xung quanh với CSS, nhưng tôi tự hỏi nếu có một cách nhanh chóng để làm cho nó hoạt động như trước đây, nhưng với phiên bản mới của JQuery. –

0

Tôi không nhớ về làm thế nào để kiểm tra radio với jQuery, nhưng có thể là như thế này:

 
<script type="text/javascript"> 
$(function() { 
    $(".question div").click(function() { 
     $(this).children("input").checked(true); 
// or 
     $(this).children("input").checked= true; 
    }); 
}); 
</script> 
+1

Bạn đã có một ý tưởng hay, mặc dù cú pháp của bạn hơi lệch. Tôi đã thử nó và nó đã hoạt động. $ (function() { \t $ ("Câu hỏi div "). Click (function() { \t \t $ (this) .children (" đầu vào ") attr (" kiểm tra", true);.. \t}); }); Cảm ơn bạn. –

+0

Tôi đã nói, tôi không nhớ rằng XD .. :) – grilix

0

Tôi biết điều này có thể không phải là câu trả lời nào cả, nhưng tôi đang viết nó vì nó đã xảy ra với tôi trước đây: Nó đã cho tôi "quá nhiều đệ quy" lỗi trong khi tôi đã sử dụng jquery và nguyên mẫu trong cùng một dự án và cũng có thể xảy ra với ajax.net với jquery, vì vậy hãy chắc chắn rằng không có xung đột giữa các thư viện nếu bạn sử dụng nhiều hơn một.

3

Chỉ lửa click() khi mục tiêu của sự kiện là div, tức là

$(function() { 
    $(".question div").click(function(event) { 
     if($(event.target).is('div')) 
      $(this).children("input").click(); 
    }); 
}); 
+0

Chỉ là những gì tôi đang tìm kiếm, cảm ơn! –

1

Vấn đề (như grilix đã nói) là sự kiện "tạo bọt" DOM, vì vậy, có một giải pháp dễ dàng cho điều đó, bạn chỉ cần hủy hiệu ứng bong bóng đó.

Bong bóng đề cập đến (tiếng Anh đơn giản) sự kiện được kích hoạt trên TẤT CẢ các yếu tố bị ảnh hưởng do vị trí của nó trong tài liệu. Vì vậy, trong ví dụ của bạn, sự kiện "click" được nhận bởi (theo thứ tự này) BODY, sau đó là cha mẹ (.question) DIV, sau đó là DIV khác và cuối cùng là INPUT.

Để làm bong bóng mà hủy bỏ, bạn có thể đi theo con đường jQuery bằng cách gọi phương pháp stopPropagation trong hàm callback của bạn, như thế này:

$(function() { 
    $(".question div").click(function(event) { 
     $(this).children("input").click(); 
     event.stopPropagation(); 
    }); 
}); 

Các đồng bằng javascript cách sẽ yêu cầu bạn phải sử dụng phương pháp cancelBubble, nhưng Tôi đoán nó nằm ngoài phạm vi câu hỏi của bạn.

Greetings, Manolo

1
<script type="text/javascript"> 
$(function() { 
    $(".question div").click(function() { 
     $(this).find("input").attr("checked", "checked"); 
    }); 
}); 
</script> 

PS: Nó được recursing quá nhiều có lẽ vì bạn đã dừng việc tuyên truyền của nhấp chuột, không phải là đầu vào divs nhấp chuột.

3

Tôi đã gặp vấn đề tương tự khi tôi định làm cho div của tôi gửi đầu vào con của nó: gửi. Điều này sẽ giải quyết vấn đề:

$(function() { 
    $(".question div").click(function() { 
     $(this).children("input").click(function(event){ 
      event.stopPropagation(); 
     }); 
     $(this).children("input").trigger("click"); 
    });}); 
Các vấn đề liên quan