使用屏幕阅读器时,提醒角色忽略aria标签



我正在为一个项目添加屏幕阅读器兼容性(我们正在使用NVDA进行测试(。在应用程序的某些部分,我们希望用户了解任何更改。我已经将role='alert'添加到元素中,它按预期工作(对内容的任何更改都会导致屏幕阅读器显示"alert",然后是元素的新内容(。然而,我们现在已经决定,我们希望警报包含更多上下文,而不是元素的确切内容,所以我添加了aria-label

当元素发生变化时,它会触发role='alert',但它以一种奇怪的方式处理aria-label。下面是一个代码片段——为了简单起见,假设typographyContent变量每30秒更改一个新的随机字符串。index变量使我们能够唯一地识别每个Typography元素——一个页面上可能有几个元素,这就是我们希望提供给用户的上下文。

const index = 1;
const typographyContent = 'I change based on some user input';
<Typography
role="alert"
aria-label={`Line ${index} now says: ${typographyContent}`}
variant="body1"
id={`line-${index}`}
>
${typographyContent}
</Typography>

假设index为1的元素中的文本更改为"I are some new content"。我希望屏幕阅读器会宣布:"提醒:第1行现在说:我是一些新内容"。它实际做的是宣布"第1行现在说:我是一些新内容。提醒:我是一些新内容`。

有没有一种简单的方法可以让它只宣布aria-label的内容,而不再次宣布元素的内容,或者我需要接受内容的重复?

我想我有一个适合你的解决方案,在Mac上的VoiceOver中进行了测试。

我认为,关键是添加aria-relevant="text"

<body>
<p
aria-live="polite"
aria-label="Line 2 now says: foobar"
aria-atomic="true"
aria-relevant="text">
foobar
</p>
<script>
(() => {
const liveRegionElement = window.document.querySelector('[aria-live]')
setInterval(() => {
const nextText = `${parseInt(Math.random() * 100)}`
liveRegionElement.setAttribute('aria-label', `Line 2 now says: ${nextText}`)
liveRegionElement.innerText = nextText
}, 2000)
})()
</script>

您可以使用aria-live属性,而不是使用alert角色。这样,内容就可以保留其原始的语义角色。

最新更新