多独立单选题组件交互异常修复:各mcq-card需独立运作
修复独立单选题组件的交互冲突问题
问题根源
你遇到的两个核心问题都是因为全局共享了状态和选择器范围:
- 单选框的
name属性重复,浏览器会把相同name的单选框归为一组,导致跨卡片的选项互斥,选新的会取消旧的 - 事件绑定和按钮状态控制用了全局选择器,操作某一题时会影响所有卡片的按钮状态
具体修复方案
1. 给每个卡片的单选框设置独立的name
复制mcq-card时,给内部单选框的name设置唯一值,比如用卡片的自定义ID区分:
<div class="mcq-card" data-card-id="1"> <h3>题目1</h3> <label><input type="radio" name="answer-1" value="选项1">选项1</label> <label><input type="radio" name="answer-1" value="选项2">选项2</label> <button class="check-btn" disabled>Check</button> </div> <div class="mcq-card" data-card-id="2"> <h3>题目2</h3> <label><input type="radio" name="answer-2" value="选项A">选项A</label> <label><input type="radio" name="answer-2" value="选项B">选项B</label> <button class="check-btn" disabled>Check</button> </div>
这样不同卡片的单选框就不会互相干扰了。
2. 基于卡片作用域绑定事件
不再用全局选择器绑定事件,而是遍历每个mcq-card,只处理当前卡片内的元素:
// 遍历所有单选题卡片 document.querySelectorAll('.mcq-card').forEach(card => { // 获取当前卡片内的单选框和按钮 const radios = card.querySelectorAll('input[type="radio"]'); const checkBtn = card.querySelector('.check-btn'); // 给当前卡片的单选框绑定选择事件 radios.forEach(radio => { radio.addEventListener('change', () => { // 只有当前卡片的按钮启用/禁用 checkBtn.disabled = !Array.from(radios).some(r => r.checked); }); }); // 给当前卡片的Check按钮绑定点击事件 checkBtn.addEventListener('click', () => { const selected = card.querySelector('input[type="radio"]:checked'); alert(`你选了:${selected.value}`); // 这里可以加你的验证逻辑,只针对当前卡片 }); });
3. 支持无限添加
以后复制mcq-card时,只要保证新卡片的data-card-id和内部单选框的name是唯一的(比如递增数字),或者用动态生成的唯一值(比如Date.now()),就能直接复用,不会再出现交互异常。
效果说明
修改后每个mcq-card完全独立:
- 选择某题选项时,只会激活当前题的Check按钮
- 操作不同题目时,选项不会互相取消
- 可以无限复制添加新题目,不需要修改JS逻辑
内容的提问来源于stack exchange,提问作者Danilo Blum
相关产品推荐
相关产品推荐

