如何检测多组单选按钮全部选是,自动设置“以上全部”单选的选中状态
单选按钮联动逻辑优化方案
原代码存在的问题
- 逻辑错误:
totalno错误赋值为.yes-radio的长度,虽然实际场景下yes和no的数量相同不会出问题,但属于隐性bug - 重复DOM查询:每次事件触发都要4次查询DOM元素,性能有冗余
- 使用
attr()设置选中状态不规范:对于表单的checked这类动态属性,应该用prop()方法修改,否则可能出现视觉状态和DOM属性不一致的问题 - 缺失边界逻辑:当前三组既不全选是也不全选否时,没有清空“全部”选项的选中状态
- 事件绑定不合理:原代码用
click事件,仅支持鼠标操作,换成change事件可以兼容键盘操作等所有触发单选状态变化的场景
优化实现方案
jQuery版本(保留原有技术栈,无冗余循环)
jQuery的选择器和筛选方法内部已经实现了遍历,无需手动写forEach循环,代码更简洁。
首先建议先修正HTML的单选name属性,保证同组单选互斥正常:
<!-- 考试A组 --> <input type="radio" class="yes-radio" name="examA"> YES <input type="radio" class="no-radio" name="examA"> NO <!-- 考试B组 --> <input type="radio" class="yes-radio" name="examB"> YES <input type="radio" class="no-radio" name="examB"> NO <!-- 考试C组 --> <input type="radio" class="yes-radio" name="examC"> YES <input type="radio" class="no-radio" name="examC"> NO <!-- 全部选项组 --> <input type="radio" class="yes-radio-all" name="allExam"> YES <input type="radio" class="no-radio-all" name="allExam"> NO
JS逻辑代码:
// 提前缓存DOM对象,避免事件触发时重复查询 const $yesRadios = $('.yes-radio'); const $noRadios = $('.no-radio'); const $allYes = $('.yes-radio-all'); const $allNo = $('.no-radio-all'); const examTotal = $yesRadios.length; // 动态获取考试组数,不用写死为3 // 绑定所有单选的change事件 $yesRadios.add($noRadios).on('change', function() { const checkedYes = $yesRadios.filter(':checked').length; const checkedNo = $noRadios.filter(':checked').length; $allYes.prop('checked', checkedYes === examTotal); $allNo.prop('checked', checkedNo === examTotal); })
原生JS forEach实现版本
如果不想依赖jQuery,用原生forEach遍历实现的写法如下:
const yesRadios = document.querySelectorAll('.yes-radio'); const noRadios = document.querySelectorAll('.no-radio'); const allYes = document.querySelector('.yes-radio-all'); const allNo = document.querySelector('.no-radio-all'); const examTotal = yesRadios.length; // 给所有考试单选绑定事件 [...yesRadios, ...noRadios].forEach(radio => { radio.addEventListener('change', () => { let yesCount = 0, noCount = 0; // 统计选中的是/否数量 yesRadios.forEach(r => r.checked && yesCount++); noRadios.forEach(r => r.checked && noCount++); // 联动全部选项 allYes.checked = yesCount === examTotal; allNo.checked = noCount === examTotal; }) })
内容的提问来源于stack exchange,提问作者samantha07
相关产品推荐
相关产品推荐

