jQuery:将更改绑定到多个复选框

13

为了提供一些背景,我有多个复选框,每个都带有不同的“分数”。当复选框更改时,我需要计算分数。我认为以下代码可以工作,但似乎.change事件没有正确绑定。

$(document).ready(function() {
   bindSomeCheckboxes();
});

function bindSomeCheckboxes() {
    var score=0;
    var checkboxes = {
        "id_1" : 3,
        "id_2" : 1,
        "id_3" : 2,
        "id_4" : 5
    };

    $.each(checkboxes, function(key, value) {
        $("#"+key).change(function(key,value) {
            if ($("#"+key).is(':checked')) {
                //add this ids value to score
            } else {
                //subtract value from score
            }
        });
    });
}  

我知道它正确地遍历了数组,但是在.change中的警报从未被看到。


应该使用:checked而不是:clicked,请查看我的答案获取更多信息。 - BrunoLM
似乎所有的答案都忽略了每个id都有一个独特的“分数”这一事实。这就是为什么我有id->score的映射。我已经进行了上面的clicked->checked更正,并更改了注释以显示我想要实现的内容。我承认我可能做错了。;) - ftdysa
我添加了一个答案,保留了你正在使用的基本结构。我认为你试图在处理程序内引用 key,以为它会有ID。问题是你给处理程序自己的 key 参数,实际上是指 event 对象。删除(或重命名)它,你就有了 key。但你不需要它,因为你有一个直接引用所需ID的引用,因为 this 引用接收事件的那个,所以 this.id 是那个的ID。 - user113716
4个回答

10

我建议您添加一个容器并一次性选择所有复选框。

至于您的问题,事件的签名是错误的,正确的是function(e){}。此外,您必须检查元素是否被选中,而不是被点击。

$("#chk").change(function(e){
    if ($(this).is(":checked"))
        alert("checked");
    else
        alert("not checked");
});
为了更方便,使用一个容器。
示例HTML。
<div id="checks">
    <input type="checkbox" id="chk1" />
    <input type="checkbox" id="chk2" />
    <input type="checkbox" id="chk3" />
    <input type="checkbox" id="chk4" />
</div>

对于分数,我更喜欢在元素上设置数据,例如:

$("#chk1").data("Score", 3);
$("#chk2").data("Score", 1);
$("#chk3").data("Score", 2);
$("#chk4").data("Score", 5);

$("#checks :checkbox").change(function(e){
    if ($(this).is(":checked"))
        alert("checked Score: " + $(this).data("Score"));
    else
        alert("not checked Score: " + $(this).data("Score"));
});

我也喜欢这种方法。谢谢你带来不同的东西,布鲁诺。 - ftdysa

6
如果你真的想采用使用ID的方法,我建议你创建一个单独的ID数组,并使用.join()创建选择器。
需要注意以下几点:
  • 不要使用.is(':clicked').is(':checked'),而是使用this.checked。这样更有效率。
  • jQuery中的事件处理程序只有一个参数,即指向event的参数。你有两个参数key,value。这使得在处理程序中的key指向event对象,而不是$.each()中的key
  • 在处理程序内部,this指向被点击的元素。
  • 因为你已经引用了元素的this,所以不需要引用$.each()中的key。你可以直接使用this.id
function bindSomeCheckboxes() {
    var score=0;
    var checkboxes = {
        "id_1" : 3,
        "id_2" : 1,
        "id_3" : 2,
        "id_4" : 5
    };

    var arrayOfIds = []; // to store array of ids

    $.each(checkboxes,function(key, val) {  // populate array with ids
        arrayOfIds.push( key );
    });

       // create a selector of the IDs
    $( "#" + arrayOfIds.join(',#') ).change(function() {
          // alert the score
        alert( checkboxes[ this.id ] );
        if ( this.checked ) {
            //do something when it is checked
        } else {
            //do something else
        }
    });
} 

谢谢。这正是我在寻找的。对我的误解进行了解释,并提供了可能的解决方案。+1 :) - ftdysa
@Magic - 不用谢。如果你有任何问题,请告诉我。:o) - user113716
哎呀,经过这么长时间的努力,我才意识到这个问题部分原因是包含这些复选框的 div 在 $(document).ready 中不可用... 调试错误真是太有趣了。 - ftdysa
@Magic - 哦,是的,那会有所不同。 :o) - user113716

4
我建议以更自然的方式获取复选框...
$("input[type='checkbox']").change(function () { 
    alert("Event is bound");
});

如果您想限制使用哪些复选框,可以添加一个类,但是如果您可以避免添加不必要的类,您的html将更加干净。


1
尝试使用'bind'和':checked'。
$.each(checkboxes, function(key, value) {
    $(this).bind('change', function() {
      if ($(this).is(':checked')) {
        //do something when it is checked
      } else {
        //do something else
      }
    });
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接