NVDA 屏幕阅读器未按预期切换到对焦模式

jen*_*DVT 3 javascript accessibility nvda

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

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

当我没有打开 NVDA 屏幕阅读器时,这个键盘功能都可以正常工作。

但是,当我打开屏幕阅读器时,不再触发嵌套的 keydown 事件。相反,即使嵌套事件是具有焦点的事件,也只会触发父事件。

但是,如果我手动将 NVDA 从“浏览模式”更改为“聚焦模式”(通过按 NVDA 键 + 空格键),那么按键事件将再次按需要工作。

不幸的是,我不能期望使用 NVDA 的人知道手动切换到“对焦模式”。它要么需要自动更改为“对焦模式”,要么需要在“浏览模式”下工作。

这是代码:

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>
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

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

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

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

aar*_*ian 5

这不是 NVDA 中的错误。

首先,你不能有嵌套的可点击元素。具体来说,您不能嵌套交互式内容。您不能嵌套链接,也不能嵌套按钮。您不能在按钮中嵌套链接,也不能在链接中嵌套按钮。还有其他类型的交互式内容也值得研究以供将来参考。

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

除了使用正确的元素(的<button>),你选择了把role=button<div>秒。HTML 验证器会传递您的代码,因为它对 nest 有效<div>

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

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

错误:已button看到开始标记,但已打开相同类型的元素。

我的建议是:

  • 不筑巢,
  • 将它们转换为<button>s,
  • 删除无效的tabindex=1(您不需要),
  • 删除对密钥代码的检查,因为<button>它免费为您提供(包括字符 32),
  • 使您<div class="result">成为ARIA 现场区域(这里有一些提示),
  • 并在按钮周围放一个包装纸,为您提供所需的视觉效果。

示例重新调整代码:

 <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>
Run Code Online (Sandbox Code Playgroud)