标准 · ARIA

状态 全局状态

aria-busy

将某个区域标记为正在更新中,使辅助技术暂不播报过渡性通知。在加载或大量 DOM 变更进行期间设为 "true";当区域稳定后切换回 "false"。

何时使用

当某个区域正在异步重建时 — 例如搜索结果列表正在流式加载、表格正在重新排序、聊天面板正在等待网络响应。若不使用 aria-busy,屏幕阅读器连接到动态区域时可能会播报每一个中间状态,既嘈杂又常令人困惑。

其使用模式如下:

  1. 在开始修改容器之前,将容器的 aria-busy="true" 设置好。
  2. 执行操作(清空子元素、获取数据、重新渲染)。
  3. DOM 稳定后,将 aria-busy="false" 设置回来。

如果该容器同时也是动态区域(aria-live="polite"aria-live="assertive"),屏幕阅读器在 aria-busy="true" 期间会暂缓播报,待 aria-busy 切换回来后再进行一次完整的统一播报。

即便在动态区域之外,该属性也仍然有用:它向辅助技术发出信号,提示用户暂时不应对内容进行操作,同时也能与进度指示器良好配合。

如何保持同步

有效值为 "true""false",默认值为 "false"(或省略)。

该属性必须覆盖整个变更过程。常见的错误是设置 aria-busy="true" 后修改 DOM,却忘记将其设置回来 — 这会导致该区域在辅助技术看来始终处于”加载中”状态,即便视觉上一切正常。

应搭配可见的加载指示器(旋转图标、骨架屏、进度文字)使用,确保视力正常的用户也能获得相同的提示。aria-busy 属性仅面向辅助技术;它本身不渲染任何内容。

常见错误

  • 设置 aria-busy="true" 后,始终未将其设回 "false"
  • 在 DOM 变更已经发生之后才设置 aria-busy — 太迟了,过渡性播报已经触发。
  • 单独使用 aria-busy,既无 aria-live,也无可见的加载动画。视力正常的用户什么都看不到;辅助技术用户什么都听不到。
  • 在整个应用的生命周期内对整个 <body> 设置 aria-busy。其作用范围应与实际发生变化的区域一致。
  • aria-busy 代替 role="progressbar" 来展示确定性进度指示器。两者是互补关系,而非替代关系。
  • 忘记同时禁用繁忙区域内的交互控件 — 视力正常的用户仍然可以看到并点击它们。

示例

<section
  id="results"
  aria-live="polite"
  aria-busy="true"
>
  <p>Loading results…</p>
</section>

<script>
  fetch('/api/search')
    .then((r) => r.json())
    .then((data) => {
      const region = document.getElementById('results');
      region.innerHTML = renderResults(data);
      region.setAttribute('aria-busy', 'false');
    });
</script>