14

想象一下,你有一个简单的单页应用程序——不管它是使用 Backbone、Angular、Ember 还是其他任何东西编写的。

当遵循路线时,您如何告诉屏幕阅读器我们已更改“页面”?

在经典应用程序中,当我导航/index.html/about.html屏幕阅读器时,显然会检测到页面更改,并按照您的预期重新阅读。

但是,在我的 Backbone 应用程序中,当我遵循一条路线时,我无法弄清楚如何触发“重读”。我尝试触发focus我在某处看到的事件,但这似乎不起作用。

注意:我目前正在使用 NVDA/Chrome 进行测试。

4

3 回答 3

19

总体而言,您不需要触发“重新阅读”,并且取决于您的 UI,这可能不是一件好事。

我的经验是使用 angular.js(作为可访问性人员而不是开发人员),我们的总体方法是管理焦点而不是触发重读。(我们进行了广泛的可访问性测试。)

从 UI 的角度来看(主要针对屏幕阅读器用户),关键是选择链接(例如about.html)应该带您到某个地方。

在这种情况下,放置焦点的适当位置将是关于“页面”内容区域的顶部,希望是<h1>.

为了使它起作用,目标元素应该可以通过脚本获得焦点,因此tabindex除非它是链接或表单控件,否则可能需要:

<h1 id="test" tabindex="-1">

-1意味着它不是默认的 tab 顺序,但可以通过脚本获得焦点。在WAI-ARIA 创作实践中查看更多信息。

然后在加载新内容的函数末尾,包括 tabindex 属性,添加如下内容:

$('#test').attr('tabindex', '-1').css('outline', 'none');
$('#test').focus();

动态添加tabindex时,最好在focus()函数之前的一行中这样做,否则它可能无法工作(我记得用 JAWS 测试过)。

为了测试这一点,我会使用:

  • 英伟达和火狐,Windows
  • Jaws 和 IE,Windows

在 Safari/OSX 上使用 VoiceOver 进行测试也很好,但工作方式不同,并且可能不会遇到与基于 Windows 的屏幕阅读器相同的问题。

你会遇到很多与 Chrome/NVDA 相关的问题,因为它没有得到很好的支持,最终用户不太可能使用它。IE 对 NVDA 没问题,但Firefox 是最好的

总体而言,值得了解 WAI-ARIA 创作实践,尤其是在 HTML 中使用 ARIA。即使您使用的是 JS 应用程序,浏览器(以及屏幕阅读器)也会解释生成的 HTML,因此建议仍然相关。

最后,如果您在没有用户按空格/回车键来激活某些内容的情况下更新页面内容,您可能会发现 JAWS/NVDA 不知道新内容,因为它们的“虚拟缓冲区”尚未更新。在这种情况下,您可能需要添加一个JS shim 以使其更新,但只有在您在测试中遇到问题时才这样做,它不应该是一个全局补丁。

于 2013-09-05T08:34:26.230 回答
8

@AlastairC和下面的评论中获取答案。我现在已经采取了更进一步的措施,并将其作为我前进的解决方案:


我的前进解决方案

我发现仅仅读出第一个标题并没有那么有用。特别是如果您所在的最后一页是加载序列。你可以听到有一些新的东西被关注,但它是否构成整个 now 页面的一部分当然不清楚。

在页面中添加一些有用的描述性文本

因此,我现在在页面布局模板的顶部有一个段落。这包括屏幕阅读器友好的消息,以及对页面内容的非常粗略的概述。

<p class="screenreader-summary" tabindex="-1">
  The <strong>Dashboard</strong> page is now on-screen.
  It contains several widgets for summarizing your data.
</p>

请注意,该tabindex值允许我们使用 JavaScript 聚焦此元素。你可能不想为此使用p元素,你可以使用任何你喜欢的东西。

将其隐藏在屏幕外(可选,仅当它会破坏您的设计/可读性时才需要)

然后将其与 CSS 相结合以将此元素移出屏幕:

.screenreader-summary {
  position: absolute;
  left:-10000px;
  top:auto;
  width:1px;
  height:1px;
  overflow:hidden;
  outline: none; /* Important, don't show an outline on-focus */
}

当屏幕上显示新页面时,聚焦此元素

最后,在屏幕上显示页面的 JavaScript 代码中(例如在 MarionetteJS 中使用onShowshow事件):

$yourViewEl.find('.screenreader-summary').focus();

结果

我是一个有视力的人,所以我说的话要小心翼翼——但是我发现阅读简短的描述会更有用。

于 2013-09-06T09:44:53.707 回答
-3

对于 Angular 的 url 变化,如果有人真的需要重新阅读所有内容,(因为要求像我一样),我们的诀窍是:

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

我们只是添加了额外的代码来处理像“成功”这样的页面,不应该发生重新加载。这模拟了实际的页面加载,屏幕阅读器将像页面更改一样正常阅读。在某种程度上违背了 Angular 的目的,但这将帮助像我这样已经拥有该应用程序并想要快速修复的人。

于 2014-11-18T21:47:01.907 回答