答题卡动态高亮需状态隔离与DOM作用域控制:用.closest('.ChoicesExam')锁定单题容器,.find()限定操作范围,避免跨题干扰;同时支持键盘操作、ARIA状态同步及兼容性样式处理。

答题卡动态高亮不是加个 class 就完事,关键在状态隔离与 DOM 作用域控制——多题共存时,点第3题选项绝不能清掉第1题的选中态。
为什么 $('.__choicesMLExam').removeClass() 会跨题失效
常见错误是用全局选择器一次性清理所有题目里的高亮类。比如执行 $('.__choicesMLExam').removeClass('__theAnswerMLExam'),结果用户刚选完第2题,第1题的已选状态也被抹掉了。
- 根本原因是没限定操作范围:DOM 查找没锚定到当前题目容器
- jQuery 的
.find()和.closest()必须配合使用,否则状态必然污染 - 重复 ID(如多个
id="choicesAExamML")会让getElementById行为不可靠,也影响屏幕阅读器定位
用 .closest('.ChoicesExam') 锁定单题作用域
每道题必须包裹在语义明确的容器里,推荐统一用 class="ChoicesExam"(不用 ID)。点击事件中通过向上查找锁定上下文:
$('body').on('click', '.__choicesMLExam', function() {
const $examContainer = $(this).closest('.ChoicesExam');
$examContainer.find('.__choicesMLExam').removeClass('__theAnswerMLExam');
$(this).addClass('__theAnswerMLExam');
});
-
.closest('.ChoicesExam')比.parents('.ChoicesExam')更安全:只取最近一层,不误匹配外层嵌套容器 - 删除动作严格限制在
$examContainer内,彻底避免跨题干扰 - 无需修改 HTML 结构或添加 data 属性,零侵入升级
移动端和键盘可访问性不能漏
答题卡要支持触屏点击和键盘 Enter/Space 触发,否则考试系统不合规。
实现 Markdown↔ HTML 互转,支持导出 PDF,用于用户请求的文档格式转换。
立即学习“前端免费学习笔记(深入)”;
- 给每个选项加
tabindex="0",确保可聚焦 - 监听
keydown事件,对Enter和Space做相同处理(防止只绑 click) - 用
aria-checked="true/false"同步状态,而不是仅靠 class;屏幕阅读器靠这个读出“已选中” - 如果选项用了
<button></button>,默认已有键盘支持,但需确认type="button"防止意外提交表单
高亮样式被裁剪?检查 overflow 和 position
有些团队用 ::before 伪元素实现高亮背景,结果在 iOS Safari 或某些 Android WebView 里显示不全。
- 父级
.__choicesMLExam不能设overflow: hidden,否则伪元素超出部分会被剪掉 - 伪元素需搭配
position: relative(在选项上)+position: absolute(在伪元素上),且z-index显式设为正数 - 更稳妥的做法是直接用
background-color+border-radius,兼容性更好,也更容易做暗色模式适配
真正难的不是让高亮“出现”,而是让它“只出现在该出现的地方”——状态边界一旦模糊,后续加自动评分、错题回看、答案导出都会连锁出错。别省那几行 .closest()。


















