嵌套菜单列表和子菜单项不会被屏幕阅读器读取为菜单和菜单项

时间:2018-04-13 12:10:12

标签: javascript html accessibility voiceover jaws-screen-reader

我有一个菜单容器,其中包含menu1,menu2等元素列表。现在每个菜单项都有一个子菜单列表(menu1有子菜单1,子菜单2等)。下面给出了带有角色属性的代码片段:

<div role="application">
  <div role="menu" class="loContainer">
    <a href="" class="loTitle">Menu1</a>
    <div role="menuitem">
        <a href="" ng-click="setTopicIdx($index)">Submenu1</a>
    </div>
    <div role="menuitem">
        <a href="" ng-click="setTopicIdx($index)">Submenu2</a>
    </div>
  </div>
</div>

这是由IE11中的JAWS 16读取&#34;菜单Menu1链接,菜单子菜单1链接,菜单子菜单2链接&#34;

在VoiceOver(iPAD AIR iOS11)中,&#34; Menu1 menuItem menuItem&#34;读取,这与JAWS行为完全相反。准确的角色是什么,以便它读取&#34;菜单Menu1,menuitem子菜单1,menuitem子菜单2&#34;?

1 个答案:

答案 0 :(得分:1)

role="menu"的所有子项都应该有role="menuitem"。您的第一个菜单项(“Menu1”)只是一个链接。尝试将其包装在<div role="menuitem">中,如子菜单。

<div role="menuitem">
  <a href="" class="loTitle">Menu1</a>
</div>

此外,出于测试目的(也许您的代码段仅用于发布此问题),请避免在示例文本中使用“menu”一词。如果您正在搜索“菜单”一词,因为您正在测试role="menu"role="menuitem",并且您的文字包含“菜单”,那么“菜单”一词即将出现的地方会让人感到困惑从。它是导致它或实际文本的角色吗?在我的示例中,我使用了:

<div role="application">
  <div role="menu" class="loContainer">
    <div role="menuitem">
      <a href="" class="loTitle">alpha</a>
    </div>
    <div role="menuitem">
      <a href="" ng-click="setTopicIdx($index)">beta</a>
    </div>
    <div role="menuitem">
      <a href="" ng-click="setTopicIdx($index)">gamma</a>
    </div>
  </div>
</div>

我注意到你正在使用role="application"。您很少需要使用该角色。大多数屏幕阅读器将自动在“浏览模式”和“表单模式”之间切换,具体取决于您选择的对象。 role="menu"是导致切换的对象之一。 (您可以更改屏幕阅读器设置,以便切换不是自动的,但我试图保持这一点。)

当屏幕阅读器切换到“表单模式”(这是role="application"强制屏幕阅读器执行的操作)时,所有键击都会传递给应用程序(您的javascript代码)而不是通过屏幕阅读器。这允许箭头键在菜单中导航,而不是通过DOM。但是,使用role="application"并不能为VoiceOver做任何事情,但它会影响您的PC用户。 WebAIM has an article解释了模式及其对VoiceOver的影响。

无论如何,我建议您从第一个role="application"中移除<div>,并确保您的菜单仍然可以与PC屏幕阅读器(如JAWS或NVDA)一起正常使用。

请记住,当您使用role="menu"时,您承诺自己管理键盘焦点。也就是说,当用户选择菜单并且屏幕阅读器用户听到“菜单”时,他们将假设他们可以使用左/右箭头键来浏览菜单。如果您允许箭头键导航,那么您应使用role="menu"。有关keyboard interaction中的菜单设计模式,请参阅“WAI-ARIA Authoring Practices 1.1”部分。