我正在努力使现有的标签组件可访问,我的设计基于W3C的Example of Tabs with Manual Activation。
<div class="tab-container" lang="en">
<div class="tabs" role="tablist">
<button class="tab" aria-selected="true" href="#" role="tab" data-tab-name="tab1" tabindex="0">
<!-- tab name -->
</button>
<!-- more tabs -->
</div>
<div class="tab-content" data-name="tab1" role="tabpanel" tabindex="0">
<!-- tab panel content -->
</div>
<!-- more tab panels -->
</div>
function getTabContent($tabContents, tabName) {
return $tabContents.filter('[data-name="' + tabName + '"]');
}
function setSelectedTab($tab) {
var tabName = $tab.data('tab-name'),
$tabSet = $tab.closest('.tabs'),
$tabContents = $tab.closest('.tab-container').find('.tab-content');
// update the tab indices and aria attributes
$tabSet.find('.tab').attr('aria-selected', 'false').attr('tabindex', '-1');
$tab.attr('aria-selected', 'true').removeAttr('tabindex');
$tabContents.addClass('hidden');
getTabContent($tabContents, tabName).removeClass('hidden');
}
function handleTabSelection(event) {
var $tab = $(event.target);
if ($tab.data('tab-name')) {
event.preventDefault();
setSelectedTab($tab);
$tab.focus();
}
}
// Our tab control needs to be used in many places on our site, we cannot guarantee that all devs will use unique IDs
// so we need to generate them here
function initTabs($tabContainer) {
var $tabList = $tabContainer.find('.tabs'),
$tabContents = $tabContainer.find('.tab-content'),
tabSetName = $tabList.data.name,
tabIdPrefix = 'tab-',
contentIdPrefix = 'tab-content-';
// add unique ids and labels
$tabList.children().each(function() {
var $tab = $(this),
tabName = $tab.data('tab-name'),
$tabContent = getTabContent($tabContents, tabName),
tabId = getUniqueId(tabIdPrefix + tabName),
contentId = getUniqueId(contentIdPrefix + tabName);
// add the unique id and associate the link with the content
$tab.attr('id', tabId).attr('aria-controls', contentId);
// add the unique id and use the link as the label for the content
$tabContent.attr('id', contentId).attr('aria-labelledby', tabId);
});
}
function getUniqueId(id, index) {
var newId = id;
if (index) {
newId += '--' + index;
index++;
} else {
index = 1;
}
if (document.getElementById(newId)) {
return getUniqueId(id, index);
}
return newId;
}
function handleKeyPress(event) {
var $tab = $(event.target);
if ($tab.is('.tab')) {
var keyCode = event.which,
$tab = $(event.target);
if (keyCode === 13 || keyCode === 32) {
// user pressed enter, or space
setSelectedTab($tab);
event.preventDefault();
} else if (keyCode === 37 || keyCode === 39) {
// the user pressed left or right
var $newTab = $tab[keyCode === 39 ? 'next' : 'prev']();
// move the focus
if ($newTab.length > 0) {
$newTab.focus();
}
event.preventDefault();
}
}
}
$('.tabs').click(handleTabSelection);
$('.tabs').keyup(handleKeyPress);
$('.tab-container').each(function() {
initTabs($(this));
});
用户可以使用左右键在选项卡列表中移动焦点,然后输入或空格键以选择选项卡。
当用户选择一个标签时,屏幕阅读器只是宣布“已选择”,在W3C的例子中,它会宣布标签名称,然后是“已选择”。
我在Firefox中使用NVDA进行测试,这是我重现的步骤:
这正是W3C的例子中发生的事情,但在我的情况下,最后一步只读“选中”。
我尝试尽可能地匹配他们的示例,但我还没弄明白如何让我的示例在激活时宣布标签名称。
什么可能导致NVDA在激活后跳过读取标签名称?
答案 0 :(得分:0)
我发现了如何解决这个问题,但到目前为止,还没有解决问题的原因。
当我在所选标签上添加select count(*), column2
from table1
group by column2
order by count(*) desc;
CSS规则时,屏幕阅读器会在选中时开始阅读内容。
after
如果我将.tab[aria-selected="true"]::after {
content: '';
}
标记添加到所有标签,则问题仍然存在;它只需要在选定的元素上。
我的猜测是,这让屏幕阅读器误以为内容已经改变,所以它会读取新的标签名称。