如何使用WAI-ARIA创建完全可访问的嵌套下拉列表?

时间:2012-07-05 18:48:21

标签: accessibility wai-aria wai

几天前,我已经开始在互联网上搜索关于WAI-ARIA的教程和文档,几乎可以用于任何类型的AJAX请求。

我习惯使用jQuery和AJAX编写嵌套下拉列表。它工作得很好,但不能原生访问。我们需要使用WAI-ARIA特定标签来“启用”所有类型的动态内容(例如AJAX)的可访问性。

我的要求之一如下: 假设我有一个State下拉列表,它使用onchange事件更新Region下拉列表。如何使用WAI-ARIA和jQuery与屏幕阅读器进行交互,以告诉用户区域下拉列表已更新?

有什么想法吗?

非常感谢!

2 个答案:

答案 0 :(得分:4)

我的2c是咏叹调控制可能更适合这里。

您在此处描述的UI听起来与您在线购买产品时经常发现的国家/州选择非常相似。这些的典型模式是:

<label for="country">Country:</label>
<select id="country" aria-controls="state">
    <option value="">Select a country...</option>
    <option value="Andorra">Andorra</option>
    <option value="Belgium">Belgium</option>
    ...
</select>
<br>
<label for="state">State:</label>
<select id="state">
    <option value="">(Select a country first)</option>
    ... options here populated when country changes ...
</select>

这里需要注意几点:

  • 我在每个选择的开头使用'占位符'选项。这有两个好处。首先,它提供了关于用户应该如何使用UI的强化文档 - 如果他们最终以某种方式最终查看第二个字段,则会将它们引导到第一个字段。其次,它避免了用户意外选择默认值:您的代码可以检查默认的“选择...”是否是提交的,并提醒用户选择实际值。另外,它隐藏了内容选项正在从用户改变的事实。

  • 但这里最重要的是,这两个选择之间的关系应该从表单或页面中的上下文中清楚。无论是否看到,遇到类似形式的用户都不需要被明确告知状态选择的内容已经改变,因为他们期望从表单设计和上下文中获得。人们知道各州都是针对一个国家的(例如德国没有“加利福尼亚州”),与县相似,所以人们已经对这些国家的运作方式有所期待。

aria-live的使用感觉不适合这里。它真正设计用于异步更新 的页面区域,否则用户必须连续轮询,来回读取,扫描更改。聊天面板可能是典型的例子:当另一端有人显示消息时,您希望屏幕阅读器在消息出现时读出消息,而不必手动寻找消息。相比之下,这里的UI更加同步;当国家发生变化时,州会在那里填充,然后(*),这是预期的行为。

ARIA确实有aria-controls="ids..."属性,这似乎更合适:规范说它用于当一个控件影响另一个控件的可见性或内容时,这似乎描述了这里发生的事情。我不知道是否有任何屏幕阅读器支持这个或者当它出现时它们会读出什么 - 我可能会调查这个并稍后更新这个答案。但无论如何,从早期的主要观点来看,无论如何,形式的行为和语义应该是显而易见的。

-

(*)如果您异步更新内容仍然存在问题 - 例如。通过ajax而不是从已经加载到页面上的数组获取县列表,那么在选择国家和结果可用于下一个选择之间可能会有延迟。 aria-live再次感觉不是正确的解决方案,因为您不想读出新内容,您只想让用户知道选择现在可以使用了。

答案 1 :(得分:1)

对于这个用例,我会添加aria-livearia-atomic属性,示例代码:

<select id="foo" aria-live="assertive" aria-atomic="true">
    <option value="nw">Northwest</option>
    <option value="ne">Northeast</option>
    <option value="se">Southeast</option>
    <option value="sw">Southwest</option>
</select>

我认为assertivearia-live属性的正确值,但polite可能是合适的。 aria-atomic属性用于告知浏览器/ AT,当存在更改时,必须将该区域作为整体呈现。您最初可能还会考虑在select上使用aria-disabled: true,然后在使用与State select相关联的值进行更新之前将其切换为false

修改

好的,我已经使用NVDA和IE9以及Firefox 13.01进行了一些测试。我目前没有JAWS可用,所以如果有人可以用JAWS测试页面会很棒。 <击> 据我所知,VoiceOver尚未支持aria属性刚刚在10.7(Lion)上使用Chrome + Voiceover进行测试,而Voiceover确实似乎支持aria-live。< / p>

Test page available here

我使用了一个简单的脚本,模拟将数据加载到区域select(使用对象):

var options = [],
    regions = {
    'nw': 'Northwest',
    'ne': 'Northeast',
    'se': 'Southeast',
    'sw': 'Southwest'
}

$(document).ready(function() {
    $.each(regions, function(key, value) {
        options.push('<option value="'+ key +'">'+ value +'</option>');
    });

    $('.block').on('change, focusout', '.states', function() {
        $(this).parent().children('.regions')
            .attr({'disabled': false, 'aria-disabled': false})
            .html(options.join(''));
    });

    window.setTimeout(
        function() {
            $('#speak').text('assertive!');
        },
        3000
    );
});

稍微玩一下后的一些观察(当涉及到屏幕阅读器时,我当然不是专家,所以如果我错过了一些让我知道的话)......

  • 建议不要使用HTML disabled属性,因为在关注状态选择之前你真的不想加载区域数据,并且因为关联的区域选择在当选项卡到下一个控件时,会跳过焦点(你可以在下面的录音中听到这一点。)奇怪的是,即使它没有聚焦,Firefox也会宣布区域选择的值。

  • 我发现politeassertive之间的行为没有区别,或者在没有aria-live属性的示例中没有区别。我认为FF13和IE9都支持aria-live,但是从最后但代码($('#speak')...)开始,看来IE9没有?

  • 也许通过AJAX模拟加载的延迟是一件好事。

您可以收听录音:IE9Firefox 13