【问题标题】:Limit checkbox select and move the selection to the first choice限制复选框选择并将选择移动到第一个选择
【发布时间】:2013-08-25 01:12:16
【问题描述】:

目标是对复选框输入列表进行选择限制。 请参阅代码,其中有三个复选框,jquery 限制最多选择三个中的两个。但是我想有一个限制,以便当两个复选框被选中并且用户尝试单击第三个未选中的框时,这会将第一个选择更改为第三个框。

http://jsfiddle.net/EYJj8/

<input type="checkbox" class="check" name="check1" id="check1" >
<label class="layout" for="check1"></label>

<input type="checkbox" class="check" name="check2" id="check2" >
<label class="layout" for="check2"></label>

<input type="checkbox" class="check" name="check3" id="check3" >
<label class="layout" for="check3"></label>

$("input:checkbox").click(function() {
var bol = $("input:checkbox:checked").length >= 2;     
$("input:checkbox").not(":checked").attr("disabled",bol);
});

【问题讨论】:

    标签: jquery html input checkbox


    【解决方案1】:

    在这种情况下,您需要实现一个状态变量来跟踪选中框的顺序。这可能看起来像这样:

    var checkState = [];
    
    $("input:checkbox").click(function() {
        if($(this).is(':checked')) {
            checkState.push(this);
            if(checkState.length > 2)
                $(checkState.shift()).prop('checked',false);
        } else {
            var ix = checkState.indexOf(this);
            if(ix > -1) checkState.splice(ix,1);
        }
    });
    

    Demo

    如果您不想以这种方式使用数组,您可以在每个复选框被选中时为其添加时间戳。但是,当您要弄清楚首先要取消选中哪个项目时,它仍然会变得有些混乱:

    $(":checkbox").change(function() {
        $box = $(this);
        $box.data('check-time', $box.is(':checked') ? (new Date().getTime()) : null);
    
        if($(':checkbox:checked').length > 2) {
            $(':checkbox:checked').sort(function(a,b) { 
                var aTime = $(a).data('check-time');
                var bTime = $(b).data('check-time');
                return aTime == bTime ? 0 : aTime < bTime ? -1 : 1;
            }).first().prop('checked', false);
        }
    });
    

    Demo

    【讨论】:

    • 我本来打算做类似的事情,但由于缺乏 IE8 支持,我打算手动做 indexOf
    • +1,这几乎是我自己整理的;虽然我建议(一如既往......)使用this.checked而不是使用jQuery来做同样的事情(因为它们都返回一个布尔值并且据我所知同样跨浏览器兼容)。
    【解决方案2】:

    看到这个demo

    $("input:checkbox").click(function () {
        if ($("input:checkbox:checked").length >= 3) {
            $("input:checkbox:checked").not(this).first().attr("checked", false);
        }
    });
    

    【讨论】:

    • 这会取消选中它找到的第一个选中的复选框,而不是第一次选中的复选框,我认为这是所要求的。
    • 是的,首先检查它不会改变。
    【解决方案3】:

    达到限制后,只需取消选中第一个 checked 复选框即可:

    $checkboxes = $('input:checkbox');
    $checkboxes.change(function() {
        if ($checkboxes.filter(':checked').length > 2) {
            $checkboxes.not(this).filter(':checked:first').prop('checked', false);   
        }
    });
    

    我绑定了change 事件而不是click 事件,这样如果复选框通过按键检查,代码仍然会被执行。

    Here's a fiddle


    编辑

    如果您想在达到限制时取消选中最后一个选中的元素,您可以执行以下操作:-

    var $checkboxes = $('input:checkbox'), lastChecked;
    $checkboxes.change(function() {
        if ($checkboxes.filter(':checked').length > 2) {
            $(lastChecked).prop('checked', false); 
        }
        if (this.checked) {
            lastChecked = this;   
        }
    });
    

    所以当一个复选框被选中,并且达到限制时,之前选中的复选框将被取消选中。

    Here's another fiddle

    【讨论】:

    • :checked:first 产生第一个被检查的 DOM 节点,而不是第一个被检查的 DOM 节点,不管它在 DOM 中的位置如何,我认为这是请求的。
    • @DavidHedlund 你可能是对的,但问题的最后一句话让我不相信
    猜你喜欢
    • 1970-01-01
    • 2011-02-21
    • 2017-07-20
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    • 2018-04-01
    • 2015-03-10
    • 2019-04-26
    相关资源
    最近更新 更多