英文:
Why the role="status" attribute doesn't work correctly?
问题
标题上说的,我的问题是为什么 role="status" 属性不能正确工作。我正在使用屏幕阅读器,但一旦段落文本被添加到主体中,它就无法读取。
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<div id="app">
<button class="btn">Click</button>
</div>
<script src="src/index.js"></script>
</body>
</html>
index.js:
const btn = document.querySelector(".btn");
btn.onclick = () => {
if (!document.querySelector(".p")) {
const p = document.createElement("div");
p.className = "p";
p.textContent = "It's a text, right?";
p.setAttribute("role", "status");
p.setAttribute("aria-live", "polite");
document.body.appendChild(p);
}
};
我也分享了一个 codesandbox 链接:
https://codesandbox.io/s/goofy-http-cm25wf?file=/src/index.js
我观看了一个关于 a11y 的会议演讲,演讲者的代码完美运行。她在演示中使用了 Svelte,而我使用的是原生 JS,但在我看来这不是问题,因为 a11y 特性并不依赖于框架。
这是她的 codesandbox(同样正常工作):
https://codesandbox.io/s/live-region-a11y-durnhc?file=/Form.svelte
英文:
As the title says, my question is why the role="status" attribute doesn't work correctly. I'm using a screen reader and it doesn't read the paragraph text once it gets appended to the body.
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<div id="app">
<button class="btn">Click</button>
</div>
<script src="src/index.js"></script>
</body>
</html>
index.js:
const btn = document.querySelector(".btn");
btn.onclick = () => {
if (!document.querySelector(".p")) {
const p = document.createElement("div");
p.className = "p";
p.textContent = "It's a text, right?";
p.role = "status";
p.ariaLive = "polite";
document.body.appendChild(p);
}
};
I share a codesandbox link as well:
https://codesandbox.io/s/goofy-http-cm25wf?file=/src/index.js
I was watching a conference talk about a11y and the code of the speaker worked perfectly. She was using Svelte for the demo and I use vanilla JS but in my opinion that's not the problem since a11y features are not framework-specific.
Here is her codesandbox (which, again, works fine):
https://codesandbox.io/s/live-region-a11y-durnhc?file=/Form.svelte
答案1
得分: 3
role="status"
是指定一个具有 aria-live="polite"
和 aria-atomic="true"
的活动区域的快捷方式。在您上面的示例中,设置 aria-live="polite"
是多余的,因为您已经使用了 role="status"
,但这并不是导致问题的原因。
活动区域将导致辅助技术,如屏幕阅读器,宣布DOM元素的更改。然而,动态添加活动区域并不一定得到支持。一些屏幕阅读器可能会宣布新添加的活动区域,而其他一些则可能不会。
新添加的DOM元素必须添加到现有的活动区域中。
因此,例如,如果我的原始代码如下所示:
<div>
</div>
然后,在用户交互后,我通过JavaScript添加了以下内容:
<div>
<div aria-live="polite">
我是新的!
</div>
</div>
新文本可能不会被宣布,因为活动区域是添加的,而不是将新文本添加到现有的活动区域中。
然而,如果原始代码如下所示:
<div aria-live="polite">
</div>
然后,新文本像这样添加:
<div aria-live="polite">
<div>
我是新的!
</div>
</div>
那么您将听到它被正确宣布。
您会注意到在您发布的 codesandbox示例 中,可以正常工作的示例中,"message" 元素已经存在于页面上,并且文本正在添加到它。该示例未添加活动区域。
<div role="status" aria-live="polite">{message}</div>
再次强调,aria-live="polite"
是不必要的,因为已经指定了 role="status"
。在我上面的示例中,您可以删除 aria-live="polite"
并使用 role="status"
来匹配您的代码。
英文:
role="status"
is a shortcut for specifying a live region with aria-live="polite"
and aria-atomic="true"
. In your example above, setting aria-live="polite"
is superfluous since you already have role="status"
, but that's not what's causing the problem.
Live regions will cause assistive technology, such as a screen reader, to announce changes to a DOM element. However, adding a live region dynamically is not necessarily supported. Some screen readers might announce the newly added live region and others might not.
The newly added DOM elements must be added to an existing live region.
So, for example, if I had:
<div>
</div>
and after some user interaction, I added the following via javascript:
<div>
<div aria-live="polite">
I'm new!
</div>
</div>
The new text might not be announced because the live region was added rather than the new text being added to an existing live region.
However, if the original code looked like this:
<div aria-live="polite">
</div>
And then new text was added like this:
<div aria-live="polite">
<div>
I'm new!
</div>
</div>
Then you would hear it properly announced.
You'll notice in the codesandbox example you posted, the one that works, the "message" element already exists on the page and text is being added to it. The example does not add the live region.
<div role="status" aria-live="polite">{message}</div>
Again, the aria-live="polite"
is not necessary since role="status"
is specified.
In my examples above, you can remove aria-live="polite"
and use role="status"
to match your code.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论