NVDA读屏器未读取最新Chrome版本的警告信息



我已经创建了下面的HTML演示页面。在该页面中,当选择";否";单选按钮。div上有aria标记;lblErr"/"lblErr2";。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Screenreader Errormessage Test with Radiobuttons</title>
</head>
<body>
<label id="instructionLbl">
Please select below
</label>
<div>
<div id="firstItemGroup">
<label id="headerTextLbl">
Select no to generate the error message
</label>
<fieldset aria-labelledby="headerTextLbl">
<div id="selectionGroup1">
<table id="radioBtnTable">
<tbody>
<tr>
<td>
<label for="button:conf:1">Yes</label>
<div class="ui-radiobutton ui-widget">
<div class="ui-helper-hidden-accessible">
<input tabindex="1" id="button:conf:1" name="button:conf" type="radio" value="false" onchange="var errorDiv = document.getElementById('lblErr');while(errorDiv.hasChildNodes()){errorDiv.removeChild(errorDiv.lastChild);}">
</input>
</div>
</div>
</td>
<td>
<label for="button:conf:2">No</label>
<div class="ui-radiobutton ui-widget">
<div class="ui-helper-hidden-accessible">
<input tabindex="2" id="button:conf:2" name="button:conf" type="radio" value="false" onchange="var errorDiv = document.getElementById('lblErr');errorDiv.style.display = 'block';var newDiv = document.createElement('div');var spanOne = document.createElement('span');spanOne.classList.add('ui-message-error-icon');var spanTwo = document.createElement('span');spanTwo.classList.add('ui-message-error-detail');var errMsg = document.createTextNode('Very long error message with special red font, details, paragraphs and recovery suggestion is displayed here');spanTwo.appendChild(errMsg);newDiv.appendChild(spanOne);newDiv.appendChild(spanTwo);errorDiv.appendChild(newDiv);">
</input>
</div>
</div>   
</td>
</tr>
</tbody>
</table>     
<div id="lblErr" style="display: none;" role="alert" aria-atomic="true" aria-live="polite" tabindex="3"></div>
</div>
</fieldset>
</div>
<div id="subItemsGroup">
<label id="headerTextLbl2">
Label with headertext
</label>
<fieldset aria-labelledby="headerTextLbl2">
<div id="selectionGroup2">
<label id="instructionLbl2">Select no to generate the error message</label>
<table id="radioBtnTable2">
<tbody>
<tr>
<td>
<label for="button:conf:3">Yes</label>
<div class="ui-radiobutton ui-widget">
<div class="ui-helper-hidden-accessible">
<input tabindex="4" id="button:conf:3" name="button:conf:2" type="radio" value="false" onchange="var errorDiv = document.getElementById('lblErr2');while(errorDiv.hasChildNodes()){errorDiv.removeChild(errorDiv.lastChild);}">
</input>
</div>
</div>
</td>
<td>
<label for="button:conf:4">No</label>
<div class="ui-radiobutton ui-widget">
<div class="ui-helper-hidden-accessible">
<input tabindex="5" id="button:conf:4" name="button:conf:2" type="radio" value="false" onchange="var errorDiv = document.getElementById('lblErr2');errorDiv.style.display = 'block';var newDiv = document.createElement('div');var spanOne = document.createElement('span');spanOne.classList.add('ui-message-error-icon');var spanTwo = document.createElement('span');spanTwo.classList.add('ui-message-error-detail');var errMsg = document.createTextNode('Very long error message with special red font, details, paragraphs and recovery suggestion is displayed here');spanTwo.appendChild(errMsg);newDiv.appendChild(spanOne);newDiv.appendChild(spanTwo);errorDiv.appendChild(newDiv);">
</input>
</div>
</div>   
</td>
</tr>
</tbody>
</table>     
<div id="lblErr2" style="display: none;" role="alert" aria-atomic="true" aria-live="polite" tabindex="6"></div>
</div> 
</fieldset> 
</div>
</div>
</body>
</html>

添加错误消息的JavaScript代码。我把它添加到onChange的单选按钮中:

var errorDiv = document.getElementById('lblErr');
var newDiv = document.createElement('div');
var spanOne = document.createElement('span');
spanOne.classList.add('ui-message-error-icon');
var spanTwo = document.createElement('span');
spanTwo.classList.add('ui-message-error-detail');
var errMsg = document.createTextNode('Very long error message with special red font, details, paragraphs and recovery suggestion is displayed here');
spanTwo.appendChild(errMsg);
newDiv.appendChild(spanOne);
newDiv.appendChild(spanTwo);
errorDiv.appendChild(newDiv);

这是我们的产品HTML/JS的提取和简化版本。在生产中,有5到6个这样的选择,一个在另一个下面,它被嵌入到一个更大的HTML结构中(有多个父div,它们也有导航元素和其他东西)。

此HTML与Google Chrome和NVDA屏幕阅读器结合使用时出现问题。在生产中,当选择";否";选择错误消息会添加到HTML中,但NVDA根本不会读取任何错误消息。Firefox中的相同情况导致NVDA读取";警报&";。

以下部分已编辑,请参阅下面的编辑

这个简化的演示片段的行为略有不同。在这里,Firefox读取了两次错误消息。一次只有消息文本,然后第二次";警报";然后是消息文本。Chrome只读取一次,并省略以"开头的第二条消息;警报";。我只想把它读成";警报"在两个浏览器中

围绕错误消息的spandiv构造在生产和我的代码段中是相同的。

我的问题是:为什么NVDA不读";警报"何时在Chrome中添加消息?这是HTML、Chrome或NVDA的问题吗?我可以通过对HTML进行不间断的更改来修复它吗?

编辑:我现在编辑了HTML/JS,这样它在Chrome中就不会读取任何错误消息,而在Firefox中仍然可以读取。改变的是divs lblErr/lblErr2现在以";显示:无";style属性,即使我在添加错误消息之前删除了它。因此Chrome/NVDA似乎忽略了对div的修改;显示:无";。这是根据规范还是Chrome中的错误?

屏幕阅读器是否说出实际单词"警报";是屏幕阅读器和浏览器组合的选择。你不能指望这个词会被宣布。如果你绝对需要公布它,那么它应该是你信息的一部分。

警报规范上写着:

";如果操作系统允许,用户代理应该通过可访问性API"触发系统警报事件

注意,";应该"并不意味着";必须";。";应该";在rfc2119中,并表示:

";3.应该用这个词或形容词";"推荐";,意思是在那里在特定情况下可能存在忽略特定项目,但必须理解其全部含义在选择另一道菜之前要仔细权衡">

也就是说,应该意味着它是鼓励的,但不是必需的。如此循环;警报";(通过发布警报系统事件)是推荐的,但不是必需的。

因此,如果你的主要问题是如何获得单词";警报";在所有平台(PC、Mac、移动设备)的所有浏览器上与所有屏幕阅读器一起宣布,然后您需要直接在错误消息中对单词进行编码。单词";警报";不必在屏幕上可见,但必须注入到活动区域中。

还要注意,role="alert"为您提供了一个隐含的aria-live="assertive"aria-atomic="true",因此您不需要指定这些属性。在您的情况下,您将覆盖隐式aria-live="assertive",并专门设置aria-live="polite"。这样做不应该伤害任何人,但你正在破坏使用警报角色的目的。

屏幕阅读器宣布实际消息一次还是两次是屏幕阅读器的决定。在Firefox上,我确实听到了两次错误消息,一次是用";警报";在Chrome上,我只听过一次,但它没有说";警报";。但在这两个浏览器上,消息都被宣布了,这就是直播区域的目的。

您在实际生产代码中提到,Chrome/NVDA上没有发布任何内容。这会很奇怪。我从未遇到过使用aria-live而消息未公布的情况。我只能对你发布的示例代码发表评论。

正如我在问题的编辑部分已经提到的,核心问题是我用JavaScript向其中添加错误消息的div的初始显示样式属性设置为";没有";。它最初也是空的。

<div id="lblErr" style="display: none;" role="alert" aria-atomic="true" aria-live="polite" tabindex="3"></div>

通过此设置,Google Chrome+NVDA不会读取动态添加的错误消息。

一旦我删除了最初的显示样式或将其更改为其他样式,谷歌Chrome+NVDA就会开始读取动态添加的错误消息。

最新更新