role="timer" 仅作语义标记,不触发读屏刷新;必须配合 aria-live="polite" 或 "assertive" 才能通知读屏,且需 aria-atomic="true" 确保完整播报,更新时应仅修改 textContent 以保持 DOM 稳定。

role="timer" 本身不触发读屏自动刷新
HTML 的 role="timer" 只是语义标记,告诉辅助技术“这是一个计时器”,但**不会主动通知读屏软件内容已变化**。即使你用 JS 每秒更新 textContent 或 innerText,NVDA、VoiceOver 等读屏器大概率静默——它们只监听特定可访问性事件(如 aria-live 变化),而非 DOM 文本的普通变更。
必须配合 aria-live="polite" 或 "assertive"
让读屏感知变化的唯一可靠方式,是把倒计时容器设为实时区域:aria-live。实际使用中:
-
aria-live="polite":适合秒级倒计时,读屏会在空闲时播报(例如“5秒”“4秒”),不打断当前语音 -
aria-live="assertive":适合关键节点(如最后3秒),会立即中断当前播报,但频繁触发易造成干扰,慎用 - 务必同时保留
role="timer",它和aria-live是互补关系:前者声明用途,后者驱动播报
示例结构:
<div role="timer" aria-live="polite" aria-atomic="true"> <span id="countdown">10</span> 秒 </div>
注意 aria-atomic="true" 很关键——它确保每次更新都读完整内容(“10秒”),而不是只读变化部分(可能只读“10”)。
立即学习“前端免费学习笔记(深入)”;
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
避免 innerHTML 覆盖导致读屏丢失焦点
如果用 element.innerHTML = newTime + " 秒",整个子树被重建,读屏可能短暂丢失上下文或跳过播报。更稳妥的做法是只更新文本节点:
- 用
textContent替代innerHTML(无 HTML 解析开销,且更安全) - 保持容器内结构稳定:不要在倒计时中动态插入/删除标签,否则
aria-atomic失效 - 若需高亮数字(如变色),用 CSS 类控制,而非包裹
<span>后再重写
正确更新方式:
const countdownEl = document.getElementById("countdown");
countdownEl.textContent = String(secondsRemaining); // 仅更新文本节点
测试时别依赖“读出来就等于可访问”
NVDA + Firefox、VoiceOver + Safari、TalkBack + Chrome 的行为有差异。常见坑:
- ChromeVox 在 Chrome 中对
aria-live支持较弱,优先用 NVDA/Firefox 或 VoiceOver/Safari 测试 - 倒计时太快(如毫秒级)会导致读屏积压或跳读,建议最低更新间隔 ≥ 500ms
- 某些读屏在页面刚加载时首次播报不及时,可在倒计时启动前给容器加个初始值并延迟 1 帧更新
真正决定是否可访问的,是读屏能否在用户需要时稳定、准确、不遗漏地播报当前值——这要求你同时控制语义(role)、通知机制(aria-live)和 DOM 稳定性(不破坏节点树)。三者缺一不可。


















