【问题标题】:Check All checkbox should be unchecked检查所有复选框应取消选中
【发布时间】:2015-02-03 22:58:29
【问题描述】:

    function toggle(source) {
      checkboxes = document.getElementsByName('options[]');
      for (var i = 0, n = checkboxes.length; i < n; i++) {
        checkboxes[i].checked = source.checked;
      }
    }
<form class="unsubscribe_form" action="process.php" method="post">
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-1" value="Option1">
  <label for="checkbox-1-1"></label>Option 1
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-2" value="Option2">
  <label for="checkbox-1-2"></label>Option 2
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-3" value="Option2">
  <label for="checkbox-1-3"></label>Option 3
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-4" value="Option3">
  <label for="checkbox-1-4"></label>Option 4
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-5" value="Option3">
  <label for="checkbox-1-5"></label>Option 5
  <input type="checkbox" class="unsubscribe-checkbox" id="checkbox-1-6" value="All" onClick="toggle(this)" />
  <label for="checkbox-1-6"></label>All
  <br>
  <input type="submit" name="formSubmit" value="Unsubscribe" />
</form>

当我选中 All 复选框时,它当然会标记所有复选框,但是一旦我取消选中一个复选框,All 复选框仍然处于选中状态。这应该是未选中的。我应该如何使用 JS 来做到这一点?

【问题讨论】:

  • 您在其他复选框上没有任何事件处理程序,这里是否缺少代码?
  • 在每个复选框上添加一个方法(例如 onClick)以取消选中/选中 checkbox-1-6。

标签: javascript html forms checkbox


【解决方案1】:

您需要将onchange 事件处理程序添加到每个复选框,并检查内部是否应选中“全部”复选框(选中所有复选框)或取消选中(至少取消选中一个)。比如这样:

var checkboxes =  [].slice.call(document.getElementsByName('options[]')),
    allCheckbox = document.querySelector('input[value="All"]');

checkboxes.forEach(function(checkbox) {
    checkbox.onchange = function() {
        if (!this.checked) {
            allCheckbox.checked = false;
        }
        else {
            var checked = checkboxes.filter(function(check) {
                return check.checked;
            });
            if (checked.length === checkboxes.length) {
                allCheckbox.checked = true;
            }
        }
    };
});

function toggle(source) {
    for (var i = 0, n = checkboxes.length; i < n; i++) {
        checkboxes[i].checked = source.checked;
    }
}
<form class="unsubscribe_form" action="process.php" method="post">
    <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-1" value="Option1">
    <label for="checkbox-1-1"></label>Option 1
    <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-2" value="Option2">
    <label for="checkbox-1-2"></label>Option 2
    <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-3" value="Option2">
    <label for="checkbox-1-3"></label>Option 3
    <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-4" value="Option3">
    <label for="checkbox-1-4"></label>Option 4
    <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-5" value="Option3">
    <label for="checkbox-1-5"></label>Option 5
    <input type="checkbox" class="unsubscribe-checkbox" id="checkbox-1-6" value="All" onClick="toggle(this)" />
    <label for="checkbox-1-6"></label>All
</form>

请注意,我使用[].slice.call 将复选框集合转换为数组,以便使用方便的数组方法。可以改用简单的 for 循环。

【讨论】:

  • 感谢 dfsq!我明白!非常感谢!
【解决方案2】:

我建议如下:

function toggle() {
  // getting a reference to all the 'name="option[]" elements:
  var options = document.getElementsByName('options[]'),
    // a reference to the 'all' checkbox:
    all = document.getElementById('checkbox-1-6');

  // if the changed checkbox is the 'all':
  if (this === all) {
    // we iterate over all the options checkboxes (using
    // Array.prototype.forEach()):
    Array.prototype.forEach.call(options, function(checkbox) {
      // and we set their checked property to the checked property
      // state of the 'all' checkbox:
      checkbox.checked = all.checked;
    });
  } else {
    // otherwise we set the 'all' checkbox to the state of
    // the Boolean returned by Array.prototype.every(),
    // which returns true if all checkboxes evaluate to
    // the condition within the function, otherwise false:
    all.checked = Array.prototype.every.call(options, function(checkbox) {
      return checkbox.checked;
    });
  }
}

// getting a NodeList of all the elements of 'class="unsubscribe-checkbox"':
var options = document.querySelectorAll('.unsubscribe-checkbox');

// iterating over them, again with Array.prototype.forEach()
// and assigning a change event-listener, which will execute the
// name function:
Array.prototype.forEach.call(options, function(opt) {
  opt.addEventListener('change', toggle);
});

function toggle() {
  var options = document.getElementsByName('options[]'),
    all = document.getElementById('checkbox-1-6');
  if (this === all) {
    Array.prototype.forEach.call(options, function(checkbox) {
      checkbox.checked = all.checked;
    });
  } else {
    all.checked = Array.prototype.every.call(options, function(checkbox) {
      return checkbox.checked;
    });
  }
}

var options = document.querySelectorAll('.unsubscribe-checkbox');

Array.prototype.forEach.call(options, function(opt) {
  opt.addEventListener('change', toggle);
});
<form class="unsubscribe_form" action="process.php" method="post">
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-1" value="Option1">
  <label for="checkbox-1-1"></label>Option 1
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-2" value="Option2">
  <label for="checkbox-1-2"></label>Option 2
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-3" value="Option2">
  <label for="checkbox-1-3"></label>Option 3
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-4" value="Option3">
  <label for="checkbox-1-4"></label>Option 4
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-5" value="Option3">
  <label for="checkbox-1-5"></label>Option 5
  <input type="checkbox" class="unsubscribe-checkbox" id="checkbox-1-6" value="All" />
  <label for="checkbox-1-6"></label>All
  <br>
  <input type="submit" name="formSubmit" value="Unsubscribe" />
</form>

您可能会注意到,我已从“全部”复选框中删除了 onClick 属性,而不是不显眼的 JavaScript,其中事件处理程序是通过 JavaScript 本身分配的(这通常会使代码更易于维护,因为要传递给给定函数的参数是在代码本身中分配的,而不必在 HTML 中单独更新)。

参考资料:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    相关资源
    最近更新 更多