几天前,我开始在互联网上搜索有关WAI-ARIA的教程和文档,以获取任何类型的AJAX请求。
我习惯于使用 jQuery 和 AJAX 编写嵌套下拉列表。它运行良好,但无法本机访问。例如,我们需要使用 WAI-ARIA 特定的标签来"启用"各种动态内容的可访问性,例如 AJAX。
我的要求之一如下:
- 假设我有一个状态下拉列表,该下拉列表使用 onchange 事件更新区域下拉列表。如何使用 WAI-ARIA 和 jQuery 与屏幕阅读器交互,以告知用户区域下拉列表已更新?
我的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 在这里感觉又不是正确的解决方案, 由于您不想读出新内容,因此您只想让用户知道选择现在可供使用。
对于这个用例,我会添加aria-live
和aria-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
,然后在使用与 State 选择关联的值更新它之前将其切换到 false
。
编辑
好的,我已经使用NVDA,IE9和Firefox 13.01做了一些测试。我目前没有可用的 JAWS,所以如果有人可以使用 JAWS 测试页面,那就太好了。据我所知,VoiceOver 尚不支持在 10.7(Lion)上使用 Chrome + Voiceover 进行了测试,并且 Voiceover 似乎确实支持 aria
属性刚刚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
);
});
玩了一下后的一些观察(在屏幕阅读器方面,我当然不是专家,所以如果我错过了什么,请告诉我)......
不建议使用 HTML
disabled
属性,因为您确实不希望在状态选择聚焦之前加载区域数据,并且由于在聚焦时禁用了关联的区域选择,因此在按 Tab 键转到下一个控件时会跳过它(您可以在下面的录音中听到这一点。奇怪的是,Firefox 会宣布区域选择的值,即使它没有集中它。我认为
polite
和assertive
之间的行为没有区别,或者在没有aria-live
属性的示例中。我以为FF13和IE9都支持aria-live
,但从最后的代码($('#speak')...
)来看,IE9似乎不支持?也许通过 AJAX 模拟加载的延迟是一件好事。
您可以收听录音:IE9,Firefox 13