如果aria-label发生变化,如何让屏幕阅读器重新读取

8
能否在aria-label的内容更改后,让屏幕阅读器重新读取选择元素?
我写了一个简单的片段,虽然没有遵循大多数aria约定,但可以展示我的意思。
如果您打开屏幕阅读器并点击div,它将会朗读标签“未选中”;如果您按下空格键,标签将会更新,但屏幕阅读器仍将保持静音。不过,如果您再次点击,则它将朗读新标签。
这是让屏幕阅读器读取更新的正确方法吗?还是有其他我不知道的方法?

let toggleSwitch = document.querySelector('.toggle-switch');

toggleSwitch.addEventListener("keyup", function(e) {
  let code = (e.keyCode ? e.keyCode : e.which);
  
  if (code == 32) {
    let nextState = toggleSwitch.getAttribute('aria-label') == 'unchecked' ? 'checked' : 'unchecked';
    
    toggleSwitch.setAttribute('aria-label', nextState);
    
  }
})
.toggle-switch {
  width: 50px;
  height: 50px;
}

.toggle-switch[aria-label="unchecked"] {
  background: red;
}

.toggle-switch[aria-label="checked"] {
  background: green;
}
Press space to change state
<div class="toggle-switch" tabindex="0" aria-label="unchecked"></div>

谢谢你的帮助。
2个回答

15

我目前从事网页无障碍工作。您的元素不需要实时读取更新内容以符合WCAG2.0(AA)的要求,只要当用户再次导航到该元素时,正确的状态被读取给用户即可。

不过,如果您确实想让它在用户使用空格或回车键激活后读出div的状态,我建议创建一个仅供屏幕阅读器使用的div,并包括aria-live="polite",然后将更改的状态注入其中。

通常,您可以使用类似于以下内容的屏幕阅读器专用类:

.sr-only {
  position: absolute;
  left:-99999px;
  height: 1px;
  width: 1px;
  overflow: hidden;
}

Aria-live会在其发生变化时向用户提示此“实时”区域中的任何文本更新,因此当用户激活您的div时,请使用新状态更新sr-only(并继续更新您的aria-label,以便在用户导航到元素并稍后返回时将其正确读出)。

注意:这不适用于标签,标签通常仅在用户导航到元素时阅读,因此即使您将aria-live附加到现有的div上,更新时也不会重新向用户读取标签 :)

编辑:请参见以下工作示例的fiddle。我只在这台机器上拥有voiceover,但它非常简单,我相当确定它也适用于JAWS和NVDA。

https://jsfiddle.net/jafarian/8hck0o3m/

更多信息

https://www.w3.org/TR/wai-aria-1.1/#aria-live


你使用多个屏幕阅读器div还是只用一个来实现多种功能? - Lotus
@j-afarian 你能指出规范中确切涉及到你在这里提到的第二句话的规则吗?我们接到了客户的 A11Y(无障碍性)审查报告,指出重新读取时屏幕阅读器未反映在按钮上 aria-label 的更改,但重新聚焦按钮将会朗读出正确的值 - 所以根据你上面所述,一切都按照规范编码,我们只是需要那个参考。或者找到一个非常简单的方法(不引入单独的活动区域,这在这里感觉有点繁琐和过度),让屏幕阅读器始终捕捉到当前的 aria-label 内容。 - Philzen
同意@Philzen的观点。状态变化必须要宣布。楼主可能在错误的方式下实施他们的解决方案。他们似乎使用aria-label来指示一个状态(他们使用"checked"/"unchecked"),所以aria-label的变化必须要宣布。通常情况下,aria-label不会改变,但如果它改变了,可能不需要宣布,如果它没有被用来指示一个状态。但正如之前提到的,它似乎被用作一个状态,所以必须要宣布。 - slugolicious

0
使用这些模式,使屏幕阅读器能够方便地在每次交互中读出控件的状态(无需任何JavaScript)。
<button aria-pressed="false">Mute Audio</button>

或者

<input id="my-a11y-button" type="checkbox" aria-checked="false">
<label for="my-a11y-button">Mute Audio</label>

OP的问题中的示例尝试实现的是一个有效的切换按钮。W3C针对这种用例有专门的建议:https://www.w3.org/WAI/ARIA/apg/patterns/button/

另外,通常最好避免将可访问元素实现为纯粹的<div>,因为对于屏幕阅读器来说,<div>只是一个逻辑设计容器,大多数实现甚至会完全忽略它,即使它具有aria-*属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接