NVDA打开自定义模态框时未播报'dialog'的原因排查
为什么NVDA不播报我的模态框为“dialog”?
你的模态框无法被NVDA正确识别并播报“dialog”,核心问题集中在以下几点:
缺少
aria-modal="true"属性
这是无障碍模态框的关键标识,它明确告知屏幕阅读器当前组件是模态弹窗,需要隔离背景内容。没有这个属性,NVDA无法完整识别其对话框角色。焦点时机与元素可见性不同步
你在添加show类后立刻调用dialog2.focus(),但浏览器此时尚未完成DOM重排,对话框刚从visibility:hidden切换为可见,NVDA来不及捕捉状态变化,因此无法触发角色播报。背景内容的无障碍处理不完整
仅给触发按钮设置aria-hidden和tabindex="-1"远远不够,模态框打开时需要将页面所有非模态内容设置为aria-hidden="true",否则屏幕阅读器可能仍会读取背景内容,干扰对话框的识别。焦点目标选择不合理
将焦点放在仅靠tabindex="-1"获得焦点的div容器上,不如放在对话框内第一个可交互元素(比如关闭按钮)更符合无障碍规范,也能让NVDA更准确触发角色播报。
修复后的代码示例
HTML
<button id="test_button2"> Open Dialog </button> <!-- 添加aria-modal="true"明确模态属性 --> <div tabindex="-1" id="test_dialog2" role="dialog" aria-labelledby="test2" aria-modal="true"> <h2 id="test2">example</h2> <p>a test paragraph</p> <button id="btnClose2">close</button> </div>
CSS
#test_dialog2 { visibility: hidden; } #test_dialog2.show { visibility: visible; padding: 1em; box-shadow: 0 0 300px rgba(0,0,0,0.5); position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; } button[aria-hidden] { opacity: .2; } *:focus { box-shadow: none; outline: 2px solid blue; }
JS
var btn2 = document.getElementById('test_button2'); var dialog2 = document.getElementById('test_dialog2'); var btnClose2 = document.getElementById('btnClose2'); var pageContent = document.body; btn2.addEventListener('click', function() { dialog2.classList.add('show'); // 延迟执行确保DOM重排完成 setTimeout(() => { // 将焦点放在关闭按钮上,符合无障碍交互逻辑 btnClose2.focus(); }, 0); // 给整个页面背景添加aria-hidden,隔离非模态内容 pageContent.setAttribute('aria-hidden', true); }); btnClose2.addEventListener('click', function() { dialog2.classList.remove('show'); pageContent.removeAttribute('aria-hidden'); btn2.focus(); });
内容的提问来源于stack exchange,提问作者Judoboy Alex
相关产品推荐
相关产品推荐

