如何获取单选组checked属性 实现跨组单选按钮全局互斥
跨单选组互斥实现方案与问题排查
现有代码存在的问题
- 循环范围错误:循环终止条件用的是
reports.length(即天数3),但页面内实际radio总数是9个(3天*3个时段),仅遍历前3个input元素,根本覆盖不到所有单选框 - 逻辑无触发时机:代码没有绑定到单选框的选中事件上,用户点击选项时不会自动执行取消选中的逻辑;且逻辑执行时会把当前刚选中的选项也一并取消,完全不符合交互预期
- 冗余DOM查询:每次循环都重新调用
getElementsByTagName获取全量input,性能差还容易出现索引错位问题 - 违背原生radio特性:原生单选框默认就支持同
name属性自动互斥,你当前分三个组必然是给不同日期的单选框设置了不同的name,才会出现跨组可同时选中的问题
实现方案
方案1:零JS原生实现(推荐)
不需要写任何额外JavaScript逻辑,只要给所有时段的单选框设置完全相同的name属性值,浏览器会自动处理互斥逻辑:选中任意一个单选框时,其他所有同name的单选框会自动取消选中,完全满足你的需求。
结合你提供的JSON数据,DOM渲染参考代码:
<div id="time-slot-wrap"></div> <script> const slotData = { report:[ {day:'Monday',slot:['9-10am','10-11am','11-12am']}, {day:'Tuesday',slot:['9-10am','10-11am','11-12am']}, {day:'Wednesday',slot:['9-10am','10-11am','11-12am']} ] }; const wrap = document.getElementById('time-slot-wrap'); slotData.report.forEach(dayConf => { const daySection = document.createElement('section'); daySection.innerHTML = `<h4>${dayConf.day}</h4>`; dayConf.slot.forEach(time => { // 核心:所有radio的name统一为time-slot daySection.innerHTML += ` <label style="display:block;margin:4px 0;"> <input type="radio" name="time-slot" value="${dayConf.day}-${time}"> ${time} </label> `; }); wrap.appendChild(daySection); }); </script>
方案2:自定义JS实现(适用于必须保留不同name的场景)
如果业务要求不同日期的单选框必须使用不同的name属性,可以通过事件监听实现跨组互斥,代码如下:
// 一次性获取页面所有单选框,避免重复查询DOM const allTimeRadios = document.querySelectorAll('input[type="radio"]'); allTimeRadios.forEach(radio => { // 给每个单选框绑定选中变化事件 radio.addEventListener('change', () => { if (!radio.checked) return; // 遍历所有其他单选框,取消选中状态 allTimeRadios.forEach(item => { if (item !== radio) item.checked = false; }); }); });
内容的提问来源于stack exchange,提问作者Salai
相关产品推荐
相关产品推荐

