JS操作HTML复选框:单函数与拆分函数的运行差异问题
问题:单函数绑定复选框时仅点击ch2生效的原因及修复
我用JavaScript操作HTML复选框时,发现调用setAttribute("disabled", "")只在点击类为“ch2”的复选框时生效,单函数绑定两个复选框的代码如下:
原问题代码
HTML
<input type="checkbox" class="ch1" name="ch1" onclick="fn_for_two_chb()"> <label for="ch1">ch1</label> <input type="checkbox" class="ch2" name="ch2" onclick="fn_for_two_chb()"> <label for="ch2">ch2</label>
JavaScript
const chb_1 = document.querySelector('.ch1') const chb_2 = document.querySelector('.ch2') function fn_for_two_chb() { if (chb_1.checked == true) { chb_2.setAttribute("disabled", ""); } else { chb_1.removeAttribute("disabled", ""); chb_2.removeAttribute("disabled", ""); } if (chb_2.checked == true) { chb_1.setAttribute("disabled", ""); } else{ chb_1.removeAttribute("disabled", ""); chb_2.removeAttribute("disabled", ""); } }
但把函数拆成两个分别绑定后功能正常:
拆分后的HTML
<input type="checkbox" class="ch1" name="ch1" onclick="fn_chb_1()"> <label for="ch1">ch1</label> <input type="checkbox" class="ch2" name="ch2" onclick="fn_chb_2()"> <label for="ch2">ch2</label>
拆分后的JavaScript
const chb_1 = document.querySelector('.ch1') const chb_2 = document.querySelector('.ch2') function fn_chb_1() { if (chb_1.checked == true) { chb_2.setAttribute("disabled", ""); } else { chb_1.removeAttribute("disabled", ""); chb_2.removeAttribute("disabled", ""); } } function fn_chb_2() { if (chb_2.checked == true) { chb_1.setAttribute("disabled", ""); } else { chb_1.removeAttribute("disabled", ""); chb_2.removeAttribute("disabled", ""); } }
原因分析
单函数里的两个if语句是顺序执行的,会互相覆盖操作:
- 点击ch1并勾选时,第一个
if会禁用ch2,但紧接着第二个if判断ch2未勾选,执行else分支把ch1和ch2的禁用状态全部移除,导致之前的禁用操作被抵消。 - 只有点击ch2并勾选时,第二个
if会禁用ch1,此时第一个if判断ch1未勾选,执行else分支移除禁用,但第二个if的操作在后,最终ch1的禁用状态会保留,看起来功能生效。
修复方案
把互斥逻辑合并,用else if避免操作覆盖,同时直接操作DOM元素的disabled属性(比setAttribute/removeAttribute更简洁直观):
修复后的单函数代码
const chb_1 = document.querySelector('.ch1') const chb_2 = document.querySelector('.ch2') function fn_for_two_chb() { // 互斥逻辑:仅允许勾选一个复选框 if (chb_1.checked) { chb_2.disabled = true; } else if (chb_2.checked) { chb_1.disabled = true; } else { // 都未勾选时,恢复两个复选框的可用状态 chb_1.disabled = false; chb_2.disabled = false; } }
另外,checked本身是布尔值,无需额外和== true比较,直接写if(chb_1.checked)更简洁。
内容的提问来源于stack exchange,提问作者elRa
相关产品推荐
相关产品推荐

