为什么我的屏幕阅读器在激活时不会通知所选标签

时间:2017-10-24 22:20:26

标签: accessibility nvda

我正在努力使现有的标签组件可访问,我的设计基于W3C的Example of Tabs with Manual Activation

You can access my demo here

HTML

<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>

JQuery的

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进行测试,这是我重现的步骤:

  1. 将焦点设置在“Nils Frahm”标签
  2. TAB
  3. 您应该听到“Agnes Obel tab of three of three”
  4. ENTER
  5. 您应该听到“Agnes Obel选项卡选中三个选项卡”
  6. 这正是W3C的例子中发生的事情,但在我的情况下,最后一步只读“选中”。

    我尝试尽可能地匹配他们的示例,但我还没弄明白如何让我的示例在激活时宣布标签名称。

    什么可能导致NVDA在激活后跳过读取标签名称?

1 个答案:

答案 0 :(得分:0)

我发现了如何解决这个问题,但到目前为止,还没有解决问题的原因。

当我在所选标签上添加select count(*), column2 from table1 group by column2 order by count(*) desc; CSS规则时,屏幕阅读器会在选中时开始阅读内容。

after

如果我将.tab[aria-selected="true"]::after { content: ''; } 标记添加到所有标签,则问题仍然存在;它只需要在选定的元素上。

我的猜测是,这让屏幕阅读器误以为内容已经改变,所以它会读取新的标签名称。

Here is the working demo