NVDA 屏幕 reader 无法按预期切换到对焦模式

NVDA screen reader not switching to focus mode predictably

我有一段简单的代码,试图在使用 NVDA 屏幕时使键盘可访问 reader。

具体来说,我有一个 div 和 "button" 的角色,另一个 div 嵌套在其中 "button" 的另一个角色。每个 div 都有一个不同的 onkeydown 事件,当用户切换到 div 并按下 "enter" 时会触发该事件。

当我没有打开 NVDA 屏幕 reader 时,此键盘功能都可以正常工作。

然而,当我打开屏幕 reader 时,嵌套的 keydown 事件不再触发。相反,即使嵌套事件具有焦点,也只会触发父事件。

但是,如果我手动将 NVDA 从 "browse mode" 更改为 "focus mode"(通过按 NVDA 键 + 空格键),那么按键事件将再次按预期工作。

不幸的是,我不能期望使用 NVDA 的人知道手动切换到 "focus mode"。它要么需要自动更改为 "focus mode",要么需要在 "browse mode."

中工作

代码如下:

HTML:

<div role="button" 
   tabindex="1" 
   onkeydown="keyEvent(event, outerDivAction)"
   class="outerDiv">
   Outer Div

   <div role="button" 
     tabindex="1"
     onkeydown="keyEvent(event, innerDivAction)"
     class="innderDiv">
     Inner Div</div>
   </div>

<div class="result"></div>

JavaScript:

function outerDivAction(event) {
  event.stopPropagation();
  console.log('outer div');
   $('.result').html('<p>outer div!</p>');
}

function innerDivAction(event) {
  event.stopPropagation();
  console.log('inner div')
  $('.result').html('<p>inner div!</p>');
}

function keyEvent(event, callback) {
  event.stopPropagation();
  if (event.which === 13) {
    callback(event);
  }
}

$('.outerDiv').click(outerDivAction);

$('.innderDiv').click(innerDivAction);

您还可以在此处查看代码笔:http://codepen.io/jennEDVT/pen/Yprova

任何人都可以提供任何帮助,我们将不胜感激!

p.s。 我知道,如果我使用嵌套的 div 并移动它,使其不再嵌套,而是第一个 div 的同级,那么一切都会按预期进行。不幸的是,这不是一个选择。 div 需要嵌套。

这不是 NVDA 中的错误。

首先,您不能嵌套可点击元素。具体来说,you cannot have nested interactive content. You cannot nest links and you cannot nest buttons. You cannot nest links in buttons, and you cannot nest buttons in links. There are other kinds of interactive content 也值得研究以备将来参考。

您可能会发现您的代码 技术上 有效,但这只是因为您编写的是谎言。

您没有使用正确的元素 (<button>),而是选择将 role=button 放在 <div> 上。 HTML 验证器会通过您的代码,因为嵌套 <div>.

是有效的

但是,通过给它们每个 role=button,您已经指示用户代理将它们视为 <button>(减去它们附带的所有好处,例如可访问性、密钥处理程序、语义、等)。

现在让我们返回并再次验证该代码,因为用户代理会看到它(嵌套 <button>s)。 W3C Nu HTML 检查器会失败(我知道是因为我 运行 测试过):

Error: Start tag button seen but an element of the same type was already open.

我的建议是:

  • 不要嵌套它们,
  • 将它们转换为 <button>s,
  • 删除无效的 tabindex=1(您不需要),
  • 取消对键码的检查,因为 <button> 免费为您提供(包括字符 32),
  • 将你的 <div class="result"> 变成 ARIA live region (there are ),
  • 并在按钮周围放置一个包装纸,以提供您想要的视觉效果。

示例重组代码:

 <div class="wrapper">
   <button class="outerDiv">
     Outer Div
   </button>
   <button class="innderDiv">
     Inner Div
   </button>
 </div>

 <div class="result" role="alert" aria-live="assertive"></div>

如果您可能感兴趣,WAI-ARIA Authoring Practices (APG) has guidance on how to make various design patterns accessible. It also includes one on what you’re describing: Menu or menubar 包含带有子菜单的菜单的代码示例。