用代码触发屏幕阅读器播报:ariaNotify() 让前端交互终于有「声音」了
用代码触发屏幕阅读器播报:ariaNotify() 让前端交互终于有「声音」了
导语
做前端交互的时候,你有没有遇到过这种场景:表单提交成功了、搜索有结果了、文件上传完了,界面上明明有变化,但用屏幕阅读器的用户就是感知不到?以前我们只能用 aria-live 塞个隐藏节点,现在浏览器原生给了你一个更直接的办法——ariaNotify(),一行代码就能让辅助技术「开口说话」。
正文
问题:动态更新对屏幕阅读器用户是盲区
现代前端应用大量依赖即时反馈:搜索框下面实时出结果、表单提交后弹个 toast、侧边栏打开个抽屉。视觉上没问题,但对依赖屏幕阅读器的用户来说,这些变化如果没有正确的无障碍标记,等于不存在。
传统的解决方案是 ARIA live region:
思路没错,但有几个真实的痛点:
- 必须改 DOM 才能触发播报,有时候你想播报的内容和页面元素无关(比如「数据已保存」这种纯状态提示);
- 屏幕外节点 hack 很常见,就是把 live region 放在
position: absolute; left: -9999px的地方,但这样可能被屏幕阅读器意外读到; - 多段消息顺序不可控,如果短时间内触发了多条通知,读屏软件可能乱序或合并处理;
- 优先级没有区分,一条「数据丢失警告」和一条「加载完成」在 live region 里没有任何优先级差异。
方案:ariaNotify() 原生 API
微软在 Edge 136 里通过 Origin Trial 引入了 ariaNotify(),现在已经写进了 MDN Web API 文档,W3C ARIA 社区组也在跟进标准化。
它的核心思路是:不用改 DOM,直接让浏览器把一段文本推给辅助技术。
基本用法
// 在任意元素上调用(文档对象也行)
const button = document.querySelector('#submit-btn');
button.ariaNotify('表单提交成功');
button.ariaNotify('文件已保存到云端', { priority: 'high' });
参数说明:
announcement:要播报的纯文本;options.priority:'normal'(默认,等当前播报完再说)或'high'(立即打断当前播报)。
与 ARIA live region 的对应关系
| 场景 | live region 做法 | ariaNotify() 做法 |
| 普通状态提示 | 更新 live region 的 textContent | `element.ariaNotify(‘已保存’)` |
| 紧急警告 | `aria-live=”assertive”` | `{ priority: ‘high’ }` |
| 纯逻辑事件(无 DOM 变化) | 需要创建隐藏 live region | 直接调用,无需 DOM |
| 多段消息合并 | 手动拼字符串 | 建议合并为一条,避免乱序 |
代码示例:实际项目里的用法
场景 1:表单提交反馈
async function handleSubmit(formData) {
try {
await submitToServer(formData);
// 成功提示——用 normal 优先级,不打断用户当前操作
document.ariaNotify('表单提交成功,感谢你的反馈');
} catch (error) {
// 错误提示——用 high 优先级,立即告知
document.ariaNotify('提交失败,请检查网络连接后重试', {
priority: 'high',
});
}
}
场景 2:搜索无结果
function showSearchEmpty(query) {
// 传统的 live region 方式
// liveRegion.textContent = `没有找到"${query}"相关结果`;
// ariaNotify 方式
searchInput.ariaNotify(`没有找到"${query}"相关结果,请尝试其他关键词`);
}
场景 3:多步骤向导
function announceStep(step, total) {
// 把多条信息合并成一条,避免读屏软件乱序
const message = `第 ${step} 步,共 ${total} 步:请填写你的联系信息`;
document.ariaNotify(message, { priority: 'normal' });
}
兼容性现状
目前 ariaNotify() 的真实支持情况:
- Edge 136+:Origin Trial 可用,需开启
--enable-blink-features=AriaNotify或通过 Origin Trial token; - 其他 Chromium 浏览器:实现中,尚未默认开启;
- Firefox / Safari:暂无公开实现计划;
- GitHub 已有 polyfill:
github/ariaNotify-polyfill,通过@live-region自定义元素模拟行为。
也就是说,现在还不能直接全量上线,但有两个落地思路:
- 渐进增强:检测
'ariaNotify' in document,有就用原生,没有回退到 live region; - 封装一层适配器:项目里统一走
a11y.announce()方法,内部自动选最优实现。
结论与判断标准
ariaNotify() 解决的其实是一个老问题:前端怎么优雅地「喊」一声。
什么时候该用它:
- 你现在的代码里已经有用隐藏 live region 做播报的逻辑 → 换成 ariaNotify() 会更干净;
- 你的事件触发和 DOM 变化没有直接关系 → ariaNotify() 比 live region 更自然;
- 你需要区分通知的优先级 →
priority: 'high'比aria-live="assertive"语义更清晰。
什么时候先等等:
- 需要支持非 Chromium 浏览器的用户占比还很高 → 先用 live region 或 polyfill;
- 你的播报逻辑已经很稳定,没有维护成本 → 不必为了用 API 而重构。
收尾
无障碍不是「等项目做完再加的功能」,它是交互设计的一部分。ariaNotify() 还没全面落地,但这个信号很明确:浏览器厂商正在把「让屏幕阅读器用户获得同等体验」这件事从「开发者自己 hack」变成「浏览器原生支持」。现在可以先把 polyfill 接上,等 Chromium 默认支持那天,你的代码已经 ready 了。
评论区
0 条评论
登录后可评论。











