首页 > 解决方案 > 函数中的循环要么跳过逻辑测试,要么没有正确评估

问题描述

当检查一系列17个复选框时,下面的功能将发射。这个想法是用户最多可以检查三个。一旦他们这样做,未选中的复选框意味着禁用自己,防止其他人被选中。如果所有三个都被选中并且用户取消选中其中一个,则应该再次启用禁用的复选框。

该代码似乎在其第一个循环中执行良好。totalChecks 变为 1。然而,在第二个循环中,它会绕过第一个 if 语句(此时,totalChecks 仍将为 1)并出于某种原因禁用所有复选框。

当我运行网页并选中任何一个复选框时,代码会将 1 添加到 totalChecks 变量。但是,在第二个循环中,似乎认为 totalChecks 大于 3,然后禁用所有复选框,包括我选择的复选框,即使 totalChecks 为 1。我的语法可能设置不正确还是我没有使用条件测试正确

我有点超出我的深度。抱歉,如果它最终成为一个简单的问题。

bark() 函数只是我写“console.log”的简写

function checkMS()
{
//first, sum the amount of checked boxes
bark("\n\n\tSection 1 - INIIALISING FUNCTION!")

var totalChecks = 0 //sets to 0 each time function is used
bark("\t\ttotalChecks initialised at "+totalChecks+".\n")

bark("\tSection 2 - ENTERING FOR LOOP!")
for(var i = 0; i < msCheckboxes.length; i++)
{
    bark("\t\tSection 2.1 - FOR LOOP: checking totalChecks < 3")
    if (totalChecks < 3)
    {
        bark("\t\t\tTotal checks is LESS than 3")
    bark("\t\t\tOn LOOP: "+i+", msCheckboxes["+i+"] is "+msCheckboxes[i].checked+".\n")
        if (msCheckboxes[i].checked == true)
        {
            msCheckboxes[i].disabled = false;
            totalChecks ++;
            bark("\ttotalChecks updated to "+totalChecks+".\n\n")
        }
    }
        else if(totalChecks == 3 && msCheckboxes[i].checked === false )
            bark("All checks used... "+totalChecks+". Disabling others")
        {
            {
                bark("Unchecked checkboxes should be disabled now")
                msCheckboxes[i].disabled = true; //disable unchecked checkboxes at limit

            }
        }
}
}

标签: javascriptarraysloopscheckbox

解决方案


您不能为此使用单个循环。首先,您需要确定是否选中了三个复选框,然后您需要禁用其他复选框。

:checked这是一种简单的方法,请参阅评论(但在使用and之后有一个更简单的方法:not(:checked)):

document.getElementById("container").addEventListener("click", function() {
  // Get the checkboxes as an array
  var cbs = Array.prototype.slice.call(document.querySelectorAll("#container input[type=checkbox]"));
  // Find out how many are checked
  var total_checked = cbs.reduce(function(sum, cb) {
    return sum + (cb.checked ? 1 : 0);
  }, 0);
  var disable = total_checked == 3;
  // Enable/disable others
  cbs.forEach(function(cb) {
    if (!cb.checked) {
      cb.disabled = disable;
    }
  });
});
<div id="container">
  <div><label><input type="checkbox" value="1"> One</label></div>
  <div><label><input type="checkbox" value="2"> Two</label></div>
  <div><label><input type="checkbox" value="3"> Three</label></div>
  <div><label><input type="checkbox" value="4"> Four</label></div>
  <div><label><input type="checkbox" value="5"> Five</label></div>
  <div><label><input type="checkbox" value="6"> Six</label></div>
  <div><label><input type="checkbox" value="7"> Seven</label></div>
  <div><label><input type="checkbox" value="8"> Eight</label></div>
  <div><label><input type="checkbox" value="9"> Nine</label></div>
  <div><label><input type="checkbox" value="10"> Ten</label></div>
</div>

或者,使用:checked伪类(感谢提醒,RobG!):

document.getElementById("container").addEventListener("click", function() {
  // How many checked checkboxes are there?
  var total_checked = document.querySelectorAll("#container input[type=checkbox]:checked").length;
  // Enable/disable the others
  var disable = total_checked == 3;
  document.querySelectorAll("#container input[type=checkbox]:not(:checked)").forEach(function(cb) {
    cb.disabled = disable;
  });
});
<div id="container">
  <div><label><input type="checkbox" value="1"> One</label></div>
  <div><label><input type="checkbox" value="2"> Two</label></div>
  <div><label><input type="checkbox" value="3"> Three</label></div>
  <div><label><input type="checkbox" value="4"> Four</label></div>
  <div><label><input type="checkbox" value="5"> Five</label></div>
  <div><label><input type="checkbox" value="6"> Six</label></div>
  <div><label><input type="checkbox" value="7"> Seven</label></div>
  <div><label><input type="checkbox" value="8"> Eight</label></div>
  <div><label><input type="checkbox" value="9"> Nine</label></div>
  <div><label><input type="checkbox" value="10"> Ten</label></div>
</div>

注意:NodeListfromquerySelectorAll最近才获得该forEach方法,但您可以简单地填充它;看到这个答案。这是上面的polyfill:

if (typeof NodeList !== "undefined" &&
    NodeList.prototype &&
    !NodeList.prototype.forEach) {
    // Yes, direct assignment is fine here, no need for `Object.defineProperty`
    NodeList.prototype.forEach = Array.prototype.forEach;
}

document.getElementById("container").addEventListener("click", function() {
  // How many checked checkboxes are there?
  var total_checked = document.querySelectorAll("#container input[type=checkbox]:checked").length;
  // Enable/disable the others
  var disable = total_checked == 3;
  document.querySelectorAll("#container input[type=checkbox]:not(:checked)").forEach(function(cb) {
    cb.disabled = disable;
  });
});
<div id="container">
  <div><label><input type="checkbox" value="1"> One</label></div>
  <div><label><input type="checkbox" value="2"> Two</label></div>
  <div><label><input type="checkbox" value="3"> Three</label></div>
  <div><label><input type="checkbox" value="4"> Four</label></div>
  <div><label><input type="checkbox" value="5"> Five</label></div>
  <div><label><input type="checkbox" value="6"> Six</label></div>
  <div><label><input type="checkbox" value="7"> Seven</label></div>
  <div><label><input type="checkbox" value="8"> Eight</label></div>
  <div><label><input type="checkbox" value="9"> Nine</label></div>
  <div><label><input type="checkbox" value="10"> Ten</label></div>
</div>


推荐阅读