在JavaScript中如何中断屏幕阅读器?NWJS游戏无障碍开发需求
NWJS游戏屏幕阅读器播报中断与无障碍优化方案
一、实现播报中断的可行方法
方法1:临时切换live区域状态
利用aria-live="off"状态终止当前播报队列,再重置状态触发新内容。屏幕阅读器会监听live区域的状态变化,切换为off会立即停止当前播报:
const gameLiveRegion = document.getElementById("game"); function interruptAndAnnounce(newText) { // 终止当前播报流程 gameLiveRegion.setAttribute("aria-live", "off"); gameLiveRegion.setAttribute("aria-label", ""); // 延迟重置状态(给屏幕阅读器100ms处理时间) setTimeout(() => { gameLiveRegion.setAttribute("aria-live", "assertive"); gameLiveRegion.setAttribute("aria-label", newText); }, 100); }
方法2:使用多独立live区域
创建两个或多个独立的live区域,每次播报切换到新区域并清空旧区域内容。新的assertive级播报会直接抢占旧的播报队列:
// 预先创建隐藏的双live区域 function createLiveRegion() { const region = document.createElement("div"); region.setAttribute("aria-live", "assertive"); region.style.cssText = "position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;"; document.body.appendChild(region); return region; } const regionA = createLiveRegion(); const regionB = createLiveRegion(); let activeRegion = regionA; function announceWithInterrupt(text) { // 切换活跃区域 activeRegion = activeRegion === regionA ? regionB : regionA; // 清空非活跃区域内容 (activeRegion === regionA ? regionB : regionA).setAttribute("aria-label", ""); // 在活跃区域触发新播报 activeRegion.setAttribute("aria-label", text); }
二、NWJS中更优的屏幕阅读器交互方式
1. 改用live区域内部文本+aria-atomic
相较于aria-label,直接修改live区域的内部文本更符合屏幕阅读器的解析逻辑,配合aria-atomic="true"确保每次播报完整内容,避免拼接混乱:
// 创建标准隐藏live区域 const standardLiveRegion = document.createElement("div"); standardLiveRegion.setAttribute("aria-live", "assertive"); standardLiveRegion.setAttribute("aria-atomic", "true"); // 强制读取完整内容 standardLiveRegion.style.cssText = "position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;"; document.body.appendChild(standardLiveRegion); function announce(text) { // 先清空再设置,确保触发更新 standardLiveRegion.textContent = ""; standardLiveRegion.textContent = text; }
2. 直接使用Web Speech API控制播报
NWJS基于Chromium,完全支持Web Speech API,可直接控制语音的播放、暂停、中断,比依赖屏幕阅读器的live区域更精准:
let currentSpeech = null; function speak(text) { // 终止当前播报 if (currentSpeech) { window.speechSynthesis.cancel(); } // 创建新的语音实例 currentSpeech = new SpeechSynthesisUtterance(text); // 可选:设置语音参数 currentSpeech.rate = 1.2; // 语速 currentSpeech.pitch = 1; // 音调 // 开始播报 window.speechSynthesis.speak(currentSpeech); } // 调用示例 speak("欢迎进入游戏"); speak("警告:生命值不足!"); // 直接中断上一句播报
内容的提问来源于stack exchange,提问作者krypek
相关产品推荐
相关产品推荐

