我有一小段代码,我在尝试使用NVDA屏幕阅读器时可以访问键盘。
具体来说,我的角色为"按钮",另一个角色为"按钮"嵌套在里面。每个div都有一个不同的onkeydown事件,当用户选中该div时会触发,并按下"输入"。
当我没有打开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>
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需要嵌套。
答案 0 :(得分:2)
这不是NVDA中的错误。
首先,您不能拥有嵌套的可点击元素。具体而言,you cannot have nested interactive content。您无法嵌套链接,也无法嵌套按钮。您不能在按钮中嵌套链接,也不能在链接中嵌套按钮。还有其他种类的interactive content值得研究以供将来参考。
您可能会发现您的代码在技术上有效,但这只是因为您所写的内容是虚假的。
您选择将<button>
放在role=button
上,而不是使用正确的元素(<div>
)。 HTML验证器会传递您的代码,因为它可以嵌套<div>
。
但是,通过向每个role=button
提供它们,您已指示用户代理将它们视为<button>
(减去它们带来的所有好处,如可访问性,键处理程序,语义等。 )。
现在让我们回过头来再次验证代码,因为用户代理会看到它(作为嵌套<button>
s)。 W3C Nu HTML检查程序会失败(我知道因为我运行了测试):
错误:看到开始标记
button
但是已经打开了相同类型的元素。
我的建议是:
<button>
s,tabindex=1
(您不需要),<button>
免费提供(包括字符32),<div class="result">
变为ARIA live region(有some tips here),示例重新调整代码:
<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>
答案 1 :(得分:1)
如果您感兴趣,WAI-ARIA Authoring Practices(APG)就如何使各种设计模式可访问有指导。它还包括一个关于你所描述的内容:Menu or menubar,其中包含带子菜单的菜单的代码示例。