role="timer"本身不触发读屏自动播报,需配合aria-live="polite"、aria-atomic="true"和aria-relevant="text"才能实现可访问倒计时;js应仅更新textcontent,避免setinterval高频刷新,并注意暂停时同步设置aria-busy。

role="timer" 本身不触发读屏自动播报
这是最常见的误解:给元素设 role="timer" 只是语义声明,读屏软件(如 NVDA、VoiceOver)**不会主动轮询或朗读内容变化**。它只在初始渲染或焦点进入时读一次,后续倒计时更新完全静默。
必须用 aria-live + role="timer" 组合
真正让读屏感知变化的是 aria-live 属性。搭配 role="timer" 才构成可访问的倒计时模式:
-
aria-live="polite":适合倒计时,避免打断用户当前操作 -
aria-atomic="true":确保整个时间字符串被完整朗读(比如“3秒”而不是“3”“秒”分开发音) -
aria-relevant="text":只监听文本内容变更,忽略样式等无关更新
示例结构:
<div role="timer" aria-live="polite" aria-atomic="true" aria-relevant="text"> 剩余 <span id="countdown">5</span> 秒 </div>
JS 更新时只需改 document.getElementById('countdown').textContent = '3' —— 不要 innerHTML 或重写整个 div,否则可能触发重复播报或中断。
避免 setInterval 频繁更新导致读屏卡顿
每秒更新一次看似合理,但 VoiceOver 在 macOS 上对高频 aria-live 变更响应滞后,连续多次变更可能堆积播报或跳过中间值。
- 推荐用
setTimeout递归控制节奏,而非setInterval - 倒计时最后 3 秒可降频为 0.5s 一次,兼顾可感知性和稳定性
- 倒计时结束时,用
aria-label显式补充状态,例如:aria-label="倒计时结束,已超时"
测试时别只依赖 Chrome + NVDA
不同读屏+浏览器组合行为差异大:
- VoiceOver + Safari:需手动聚焦到 timer 元素才开始监听,首次加载后常需 tab 进入
- JAWS + IE/Edge:对
aria-atomic支持不稳定,有时仍会分字朗读 - Android TalkBack:依赖
android:accessibilityLiveRegion,网页中靠aria-live模拟,但延迟更高
真实验证必须用目标用户常用组合,且关闭“静音模式”和“仅朗读更改”等辅助设置。
最易被忽略的是:倒计时暂停/恢复时,必须同步更新 aria-busy="true" 状态,并在恢复后清除 —— 否则读屏可能持续播报旧值。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











