提问人:Levi Wallach 提问时间:9/1/2021 更新时间:9/9/2021 访问量:2358
你能模糊一组复选框吗?
Can you onblur a set of checkboxes?
问:
我有一组复选框和验证,以便在提交时至少需要选中其中一个复选框。但是我希望能够在用户模糊出复选框集时设置验证错误。问题是,如果我对最后一个进行模糊处理,它将不起作用,因为它们可能会将 Shift Tab 键切换到倒数第二个复选框。我试过但 fieldset 标签中的 onblur,但这根本没有触发模糊。这只是一个纯 html 和普通 JS 无法克服的限制吗?
答:
1赞
epascarello
9/1/2021
#1
您可以查看下一个聚焦的元素是什么,并确定它们是否属于同一分组。
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>
评论
0赞
Levi Wallach
9/9/2021
谢谢你的想法。我使用其中一些来构建一个更具体地针对我的情况的函数。请注意,您的 fieldSet.querySelector(“input:checked”) !== null;对我不起作用,我不得不使用 document.querySelector(“fieldset”).querySelectorAll(“input:checked”).length。
0赞
Levi Wallach
9/9/2021
#2
根据 epascarello 的建议,我能够创建一个函数,该函数提供与所提供的功能类似的功能。我在复选框下方有一个错误跨度。我想要的行为是,如果选中任何复选框,就会立即删除它,但只有在用户模糊了整套复选框时才添加错误范围。请注意,此页面上只有一个字段集,并且错误范围具有我可以引用的特定 ID。这是我开始工作的功能:
document.querySelectorAll('input[type="checkbox"]').forEach((elem) => {
elem.addEventListener("blur", function (event) {
var errorSpan = document.getElementById("checkboxesErrorSpan");
var isValid = document.querySelector("fieldset").querySelectorAll("input:checked").length > 0;
if (isValid) {
if ((errorSpan.style.display == "inline")) {
errorSpan.style.display = "none";
}
}
else {
if (event.relatedTarget.type != "checkbox") {
if ((errorSpan.style.display == "none")) {
errorSpan.style.display = "inline";
}
}
}
});
});
评论