我们正试图用一个巨型菜单构建一个非常特殊的交互/动画,这将使我们找到一个需要从层次结构中提取顶级项目的解决方案。
例如,理想的标记通常是这样的:
<ul>
<li>Fruit
<ul>
<li>Apple</li>
<li>Banana</li>
</ul>
</li>
<li>Vegetables
<ul>
<li>Radish</li>
<li>Potato</li>
</ul>
</li>
<li>Meat
<ul>
<li>Chicken</li>
<li>Beef</li>
</ul>
</li>
</ul>
它是分层的,通过键盘和语音反馈导航相当容易。
对于我们希望创建的交互,我们真的需要这样两个层次完全分离的东西:
<ul>
<li>Fruit</li>
<li>Vegetables</li>
<li>Meat</li>
</ul>
<div>
<ul>
<li>Apple</li>
<li>Banana</li>
</ul>
<ul>
<li>Radish</li>
<li>Potato</li>
</ul>
<ul>
<li>Chicken</li>
<li>Beef</li>
</ul>
</div>
这还能像前者一样容易访问吗?如果是这样,需要做些什么来确保良好的键盘导航和屏幕阅读器兼容性?
您需要将其标记为ARIA菜单。正确的标记如下:
<ul role="menubar">
<li role="menuitem" aria-haspopup="true" aria-owns="fruitmenu" tabindex="0">Fruit</li>
<li role="menuitem" aria-haspopup="true" aria-owns="vegmenu" tabindex="-1">Vegetables</li>
<li role="menuitem" aria-haspopup="true" aria-owns="meatmenu" tabindex="-1">Meat</li>
</ul>
<div>
<ul role="menu" id="fruitmenu" aria-expanded="true" >
<li role="menuitem" tabindex="-1">Apple</li>
<li role="menuitem" tabindex="-1">Banana</li>
</ul>
<ul role="menu" id="vegmenu" aria-expanded="false" >
<li role="menuitem" tabindex="-1">Radish</li>
<li role="menuitem" tabindex="-1">Potato</li>
</ul>
<ul role="menu" id="meatmenu" aria-expanded="false" >
<li role="menuitem" tabindex="-1">Chicken</li>
<li role="menuitem" tabindex="-1">Beef</li>
</ul>
</div>
然后,您需要使用JavaScript来实现控制,以管理菜单的展开/折叠,并操纵tabindex属性进行焦点管理(加上移动焦点)和展开aria(尽管根据JavaScript键盘的处理,这可能是多余的。
以下是Polymer中可访问ARIA菜单实现的示例,尽管由于Polymer的影子DOM模拟中的名称空间问题,ID并不是唯一的。
jQuery ARIA菜单库
原生Web组件、聚合物和Angular2 ARIA菜单实现