Aria-live 更新后不说标签
Aria-live doesn't say label after updates
我有这篇HTML是用JS动态更新的。屏幕 reader 仅在更新时读出新值。它没有说更新的输入标签。
<ul class="points-transfer-detail-points-calculation clearfix">
<li>
<label for="points-to-transfer">{{{ pointsToTransferLabel }}}</label>
<input id="points-to-transfer" type="text" aria-controls="brand-points points-left-after-transfer" placeholder="XXX,XXX" {{#if disabled }}disabled{{/if}}>
<p id="points-to-transfer-error" class="points-transfer-detail-form-error" aria-hidden="true" role="alert">{{{ pointsToTransferErrorMessage }}}</p>
</li>
<li>
<label for="brand-points">{{{ brandPointsLabel }}}</label>
<input id="brand-points" type="text" aria-live="polite" aria-atomic="true" disabled>
</li>
<li>
<label for="points-left-after-transfer">{{{ pointsLeftLabel }}}</label>
<input id="points-left-after-transfer" type="text" aria-live="polite" aria-atomic="true" disabled>
</li>
</ul>
我尝试使用 aria-labelledby
、aria-describedby
、role="alert"
和 aria-label
但没有结果,只有输入的值,而不是他的标签。
根据我对 Google 和 Whosebug 的所有研究,我未能找到合适的答案。
我在 Firefox 中使用 NVDA 作为屏幕 reader。
感谢您的帮助。
标签唯一应该被屏幕读取的时间 - reader 是当焦点放在其相应字段上时。
您的输入字段全部被禁用。因此,标签不会被读取,因为您无法专注于字段。
从输入字段中删除 aria-live 和 aria-atomic。它们在输入字段上不可用。 Aria-live 在其分配给的容器内发生 DOM 更改时触发。输入字段不是容器。另外,无论如何都不应该这样宣布标签。
如果您想宣布对 DOM 的更改,我建议将内容注入页面底部的空 aria-live div 并将其隐藏起来。
这是一个包含 1 个静态标签和 3 个动态标签的工作示例。一种使用 "disabled" 属性,一种使用 aria-disabled 以便它仍然可以获得焦点。关于新标签呈现的公告也使用可访问的隐藏 aria-live 容器。
这已经在 FF 中的 NVDA、IE 中的 JAWS 和 Safari 中的 VO 中进行了测试。
(function () {
function populateLabels () {
document.querySelector('[for="dogsName"]').appendChild(document.createTextNode('Dog\'s Name'));
document.querySelector('[for="catsName"]').appendChild(document.createTextNode('Cat\'s Name'));
document.querySelector('[for="lastName"]').appendChild(document.createTextNode('Last Name'));
}
function announceChange () {
var announcement = "Some new labels have appeared. They are Last Name, Dog's Name, and Cat's Name.",
ariaLiveContainer = document.querySelector('[aria-live]');
ariaLiveContainer.appendChild(document.createTextNode(announcement));
setTimeout(function () {
ariaLiveContainer.innerHTML("");
}, 2000);
}
setTimeout(function () {
populateLabels();
announceChange();
}, 3000);
}());
input {
border: 1px solid black;
}
[disabled],
[aria-disabled="true"] {
border: 1px solid #ccc;
background-color: #eee;
}
.acc-hidden { /* Hide only visually, but have it available for screenreaders */
position: absolute !important;
display: block;
visibility: visible;
overflow: hidden;
width: 1px;
height: 1px;
margin: -1px;
border: 0;
padding: 0;
clip: rect(0 0 0 0);
}
<p>The first label is there on DOM load. The other three labels come in 3 seconds after DOM load. An announcement is made about the updated labels.</p>
<form action="">
<ul>
<li>
<label for="firstName">First Name</label>
<input type="text" name="first-name" id="firstName" />
</li>
<li>
<label for="lastName"></label>
<input type="text" name="last-name" id="lastName" />
</li>
<li>
<label for="dogsName"></label>
<input type="text" name="dogs-name" id="dogsName" disabled /> (uses the disabled attribute -- doesn't receive focus)
</li>
<li>
<label for="catsName"></label>
<input type="text" name="cats-name" id="catsName" aria-disabled="true" /> (uses the aria-disabled="true" attribute -- can receive focus)
</li>
</ul>
</form>
<div class="acc-hidden" aria-live="polite"></div>
我有这篇HTML是用JS动态更新的。屏幕 reader 仅在更新时读出新值。它没有说更新的输入标签。
<ul class="points-transfer-detail-points-calculation clearfix">
<li>
<label for="points-to-transfer">{{{ pointsToTransferLabel }}}</label>
<input id="points-to-transfer" type="text" aria-controls="brand-points points-left-after-transfer" placeholder="XXX,XXX" {{#if disabled }}disabled{{/if}}>
<p id="points-to-transfer-error" class="points-transfer-detail-form-error" aria-hidden="true" role="alert">{{{ pointsToTransferErrorMessage }}}</p>
</li>
<li>
<label for="brand-points">{{{ brandPointsLabel }}}</label>
<input id="brand-points" type="text" aria-live="polite" aria-atomic="true" disabled>
</li>
<li>
<label for="points-left-after-transfer">{{{ pointsLeftLabel }}}</label>
<input id="points-left-after-transfer" type="text" aria-live="polite" aria-atomic="true" disabled>
</li>
</ul>
我尝试使用 aria-labelledby
、aria-describedby
、role="alert"
和 aria-label
但没有结果,只有输入的值,而不是他的标签。
根据我对 Google 和 Whosebug 的所有研究,我未能找到合适的答案。
我在 Firefox 中使用 NVDA 作为屏幕 reader。
感谢您的帮助。
标签唯一应该被屏幕读取的时间 - reader 是当焦点放在其相应字段上时。
您的输入字段全部被禁用。因此,标签不会被读取,因为您无法专注于字段。
从输入字段中删除 aria-live 和 aria-atomic。它们在输入字段上不可用。 Aria-live 在其分配给的容器内发生 DOM 更改时触发。输入字段不是容器。另外,无论如何都不应该这样宣布标签。
如果您想宣布对 DOM 的更改,我建议将内容注入页面底部的空 aria-live div 并将其隐藏起来。
这是一个包含 1 个静态标签和 3 个动态标签的工作示例。一种使用 "disabled" 属性,一种使用 aria-disabled 以便它仍然可以获得焦点。关于新标签呈现的公告也使用可访问的隐藏 aria-live 容器。
这已经在 FF 中的 NVDA、IE 中的 JAWS 和 Safari 中的 VO 中进行了测试。
(function () {
function populateLabels () {
document.querySelector('[for="dogsName"]').appendChild(document.createTextNode('Dog\'s Name'));
document.querySelector('[for="catsName"]').appendChild(document.createTextNode('Cat\'s Name'));
document.querySelector('[for="lastName"]').appendChild(document.createTextNode('Last Name'));
}
function announceChange () {
var announcement = "Some new labels have appeared. They are Last Name, Dog's Name, and Cat's Name.",
ariaLiveContainer = document.querySelector('[aria-live]');
ariaLiveContainer.appendChild(document.createTextNode(announcement));
setTimeout(function () {
ariaLiveContainer.innerHTML("");
}, 2000);
}
setTimeout(function () {
populateLabels();
announceChange();
}, 3000);
}());
input {
border: 1px solid black;
}
[disabled],
[aria-disabled="true"] {
border: 1px solid #ccc;
background-color: #eee;
}
.acc-hidden { /* Hide only visually, but have it available for screenreaders */
position: absolute !important;
display: block;
visibility: visible;
overflow: hidden;
width: 1px;
height: 1px;
margin: -1px;
border: 0;
padding: 0;
clip: rect(0 0 0 0);
}
<p>The first label is there on DOM load. The other three labels come in 3 seconds after DOM load. An announcement is made about the updated labels.</p>
<form action="">
<ul>
<li>
<label for="firstName">First Name</label>
<input type="text" name="first-name" id="firstName" />
</li>
<li>
<label for="lastName"></label>
<input type="text" name="last-name" id="lastName" />
</li>
<li>
<label for="dogsName"></label>
<input type="text" name="dogs-name" id="dogsName" disabled /> (uses the disabled attribute -- doesn't receive focus)
</li>
<li>
<label for="catsName"></label>
<input type="text" name="cats-name" id="catsName" aria-disabled="true" /> (uses the aria-disabled="true" attribute -- can receive focus)
</li>
</ul>
</form>
<div class="acc-hidden" aria-live="polite"></div>