1

几天前,我开始在 Internet 上搜索有关 WAI-ARIA 的教程和文档,以了解几乎所有类型的 AJAX 请求。

我习惯于使用 jQuery 和 AJAX 编码嵌套的下拉列表。它工作得很好,但不是本机可访问的。例如,我们需要使用 WAI-ARIA 特定标签来“启用”各种动态内容(例如 AJAX)的可访问性。

我的要求之一如下:

  • 假设我有一个 State 下拉菜单,它使用 onchange 事件更新 Region 下拉菜单。如何使用 WAI-ARIA 和 jQuery 与屏幕阅读器进行交互,以告知用户 Region 下拉列表已更新?
4

2 回答 2

4

我的 2c 是 aria-controls 可能更适合这里。

您在此处描述的 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 在这里不再是正确的解决方案,因为您不想读出新内容,您只想让用户知道选择现在可以使用了。

于 2012-07-06T03:56:25.390 回答
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>

我认为这assertive是该aria-live属性的正确值,但polite可能更合适。该aria-atomic属性用于告诉浏览器/AT,当发生更改时,必须将区域作为一个整体呈现。您也可以考虑aria-disabled: true最初在选择上使用,然后false在使用与状态选择关联的值更新它之前将其切换到。

编辑

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

此处提供测试页面

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

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
    );
});

玩了一会儿之后的一些观察(我当然不是屏幕阅读器方面的专家,所以如果我错过了什么,请告诉我)......

  • 不建议使用 HTMLdisabled属性,因为您真的不希望在状态选择被聚焦之前加载区域数据,并且由于关联的区域选择在聚焦时被禁用,因此在跳到下一个控件时会跳过它(您可以在下面的录音中听到这一点。)奇怪的是,Firefox 会宣布区域选择的值,即使它没有聚焦它。

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

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

您可以收听录音:IE9Firefox 13

于 2012-07-05T21:29:21.603 回答