可访问性测试与治理
可访问性测试分层进行:静态规则工具能发现缺少 label、对比度或非法 ARIA 的风险;组件测试验证 role、name、键盘和状态变化;真实浏览器和人工读屏验证焦点、滚动、手势、缩放及复杂组合控件。任何一层都不能单独证明全部可用。
js
const button = document.querySelector('button[aria-expanded]')
button.click()
console.assert(button.getAttribute('aria-expanded') === 'true')测试应断言用户可观察的语义,不要只断言 CSS class。治理上把可访问性纳入设计验收、代码评审、回归测试和发布监控,避免上线前一次性补救。
练习
为对话框写三层验收:DOM 语义、键盘交互、真实浏览器;分别列出上一层无法证明的一个问题。
核心机制与实现
无障碍实现是语义、键盘、焦点、名称、状态和动态反馈的组合;ARIA 只能补足缺失语义,不能替代原生元素。
围绕“可访问性测试与治理”先写出输入 → 中间状态 → 可观察结果,再实现最小闭环。不要把事件监听、异步请求、DOM 读取或 store 写入混在一个函数里;每个副作用都要有创建、完成、取消和清理路径。
html
<button aria-expanded="false" aria-controls="menu">菜单</button>
<div id="menu" hidden>...</div>
<script>
button.addEventListener('click', () => {
const open = button.getAttribute('aria-expanded') === 'true'
button.setAttribute('aria-expanded', String(!open))
menu.hidden = open
})
</script>逐步运行:先只验证成功路径,再改变一个输入;记录时间顺序、对象身份、错误类型和最终可见状态。若环境不支持某个浏览器 API,要把静态协议验证和真实浏览器验证分开记录。
失败边界与变体
- 输入为空、重复、过期或非法时,不应静默覆盖有效状态。
- 组件卸载、路由离开、标签页关闭或请求取消时,资源必须停止写入。
- 跨文档、Shadow DOM、Worker、SSR 或多标签页会改变可见边界,不能沿用单页面直觉。
- 需要持久化时记录 schema 版本和迁移失败策略;需要全局状态时先证明局部状态不足。
可运行实验与练习
使用键盘完成打开、移动、关闭和返回焦点;用辅助技术或浏览器无障碍树核对名称、角色、状态、错误和动态更新。
练习要求:实现一个最小版本,补一个失败测试,再给出一个替代方案及其适用条件。答案应包括实际输入序列、观察结果、修复原因和未覆盖的浏览器差异。