首页 > 解决方案 > 你能模糊一组复选框吗?

问题描述

我有一组复选框和验证,以便在提交时至少需要检查其中一个复选框。但是,如果用户模糊了一组复选框,我希望能够设置验证错误。问题是,如果我对最后一个进行模糊处理,它就不起作用,因为它们可能会切换到倒数第二个复选框。我已经尝试过在 fieldset 标记中使用 onblur ,但这根​​本没有触发模糊。这只是普通 html 和 vanilla JS 无法克服的限制吗?

标签: javascripthtmlvalidation

解决方案


您可以查看下一个关注的元素是什么,并确定它们是否属于同一组。

document.querySelectorAll('input[type="checkbox"]').forEach((elem) => {
  elem.addEventListener("blur", function (event) {
    const nextElem = event.relatedTarget;
    const fieldSet = elem.closest('fieldset');
    const isValid = fieldSet.querySelector("input:checked") !== null;
    if (nextElem?.closest('fieldset') !== fieldSet) {
        fieldSet.classList.toggle("error", !isValid);
    } else if (isValid) {
        fieldSet.classList.remove("error");
    }
  });
});
.error {
  color: red;
}
<form>
  <fieldset>
    <legend>Pizza One</legend>

    <input type="checkbox" name="x1-1" id="x1-1">
    <label for="x1-1">Cheese</label>

    <input type="checkbox" name="x1-2" id="x1-2">
    <label for="x1-2">Peppers</label>

    <input type="checkbox" name="x1-3" id="x1-3">
    <label for="x1=3">Mushrooms</label>

  </fieldset>

  <fieldset>
    <legend>Pizza Two</legend>

    <input type="checkbox" name="x2-1" id="x2-1">
    <label for="x2-1">Cheese</label>

    <input type="checkbox" name="x2-2" id="x2-2">
    <label for="x2-2">Peppers</label>

    <input type="checkbox" name="x2-3" id="x2-3">
    <label for="x2-3">Mushrooms</label>

  </fieldset>

  <input type="submit" />
</form>

添加使用 HTML5 验证的技巧

document.querySelectorAll('input[type="checkbox"]').forEach((elem) => {
  elem.addEventListener("blur", function(event) {
    const nextElem = event.relatedTarget;
    const fieldSet = elem.closest('fieldset');
    const isValid = fieldSet.querySelector("input:checked") !== null;
    if (nextElem?.closest('fieldset') !== fieldSet) {
      fieldSet.classList.toggle("error", !isValid);
    }
  });

  elem.addEventListener("change", function(event) {
    const fieldSet = elem.closest('fieldset');
    const isValid = fieldSet.querySelector("input:checked") !== null;
    if (isValid) {
      fieldSet.classList.remove("error");
      fieldSet.querySelectorAll("input").forEach((cb) => {
        cb.removeAttribute("required");
      });
    } else {
      fieldSet.querySelectorAll("input").forEach((cb) => {
        cb.setAttribute("required", "required");
      });
    }
  });

  const changeEvt = document.createEvent("HTMLEvents");
  changeEvt.initEvent("change", false, true);
  elem.dispatchEvent(changeEvt);
});
.error {
  color: red;
}
<form>
  <fieldset>
    <legend>Pizza One</legend>

    <input type="checkbox" name="x1-1" id="x1-1">
    <label for="x1-1">Cheese</label>

    <input type="checkbox" name="x1-2" id="x1-2">
    <label for="x1-2">Peppers</label>

    <input type="checkbox" name="x1-3" id="x1-3">
    <label for="x1=3">Mushrooms</label>

  </fieldset>

  <fieldset>
    <legend>Pizza Two</legend>

    <input type="checkbox" name="x2-1" id="x2-1">
    <label for="x2-1">Cheese</label>

    <input type="checkbox" name="x2-2" id="x2-2">
    <label for="x2-2">Peppers</label>

    <input type="checkbox" name="x2-3" id="x2-3">
    <label for="x2-3">Mushrooms</label>

  </fieldset>

  <input type="submit" />
</form>


推荐阅读