如何在Angular更改状态时使屏幕阅读器读取整个页面?

6

需求:每次页面更改时,屏幕阅读器必须朗读整个页面内容。

我们使用firefox+NVDA进行测试,由于angular不会“更改页面”,因此我们尝试了以下几种方法,以使其在更改状态时朗读整个页面:

aria-live="assertive"

这主要是针对我们网站中文本的更改,但它只读取正在添加的内容,在我们的情况下,我们有一个使用ng-repeat填充的表格,它读取正在添加的信息,但没有任何上下文(它不说正在读取哪一行或列)。

另一个问题是表单,在被Angular填充之前,屏幕阅读器将其读取,这可以通过使用$timeout解决。但是,当aria-live读取更改时,它会跳过某些部分,如果我们添加了aria-atomic来强制读取,则会读取一些包含多个选项的选择框(所有选项都被读取,我们有超过一百个选项),这不是屏幕阅读器的正常读取方式,它们仅读取前十个选项或单击后可见的选项。

请记住,如果没有aria-livearia-atomic,当您在Angular中更改状态时,用户将不会收到任何更改通知。

几乎放弃之后,我们决定可能我们的重点错了,我们需要使每个状态成为自己的页面,因此我们使用了以下方法:

function ForceNVDARead() {
    $(window).on('hashchange', function () {
        location.reload();
    });
}

每次更改URL都会强制重新加载,这很有效,一切都被正确读取,我们几乎认为这解决了所有问题。但是这会导致客户端向我们的服务器发送重复请求。
有没有办法使NVDA像常规页面加载一样读取angular状态的内容,而不必强制重新加载页面?
请不要说只使用aria-roles或类似于此的东西,因为这对此无效,而且我们已经有了它们,我们需要应用程序在更改状态时阅读所有内容。
非常感谢任何帮助,我们即将放弃,并重新启动没有angular的项目,因为我们无法满足我们的无障碍要求。

你在页面上添加 aria-live="assertive" 的位置在哪里?是在整个body本身上?还是在表格上? - haxxxton
你能否尝试在整个页面上组合使用 aria-live="polite" aria-atomic="true" aria-relevant="additions removals",或者使用Angular的 $stateChangeStart$stateChangeSuccess 事件在各自元素上“切换”aria值的存在(不幸的是,我目前无法测试这些建议)? - haxxxton
我们实际上已经尝试了很多方法,但都没有起作用。问题主要出在表单上,当你想编辑某些内容时,由于填充字段的原因,有些字段不会改变,因此我们无法手动在每个字段上添加aria-live,因为并非所有字段都会更改/读取。 - luisluix
1个回答

9
要求:在每个页面更改时,屏幕阅读器必须读取整个页面内容。
从可访问性的角度来看,这基本上不是一个要求,它相当于让人们逐行阅读屏幕上的所有内容,或使用readquick,这不是自然的用法。
使用Angular时可以实现屏幕阅读器的可访问性,但我们需要重置一些假设:
  • 当您有页面更新时,关键是管理焦点并移动到新内容。这样可以让人们以自己的方式阅读,而不是您一直假定他们必须阅读的方式。
  • ARIA live适用于页面上其他位置(远离键盘焦点)的小型更新,而不是整个内容,它不是答案,我会完全放弃它。
  • 如果人们在加载表单之前阅读表单,则可能是试图通过ARIA-live强制阅读的副作用。如果不是,则尝试使用焦点管理在加载表单时将焦点放在表单顶部。
  • 最好阅读NVDA使用教程,或与“本地”用户交谈。从我的经验来看,您没有像最终用户那样使用它,因此更好地了解“正常”交互是什么样子的。
如果您放弃使用ARIA-live并采用焦点管理,您可能会解决大多数问题,但从不同的角度可能会有更多问题。

根据这个问题的浏览量,很多像我一样的人可能有相同的需求,我觉得这很有趣。 - luisluix

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