为什么 role=”status” 属性不能正常工作?

huangapple go评论66阅读模式
英文:

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:

&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Parcel Sandbox&lt;/title&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div id=&quot;app&quot;&gt;
      &lt;button class=&quot;btn&quot;&gt;Click&lt;/button&gt;
    &lt;/div&gt;

    &lt;script src=&quot;src/index.js&quot;&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;

index.js:

const btn = document.querySelector(&quot;.btn&quot;);

btn.onclick = () =&gt; {
  if (!document.querySelector(&quot;.p&quot;)) {
    const p = document.createElement(&quot;div&quot;);
    p.className = &quot;p&quot;;
    p.textContent = &quot;It&#39;s a text, right?&quot;;
    p.role = &quot;status&quot;;
    p.ariaLive = &quot;polite&quot;;
    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=&quot;status&quot; is a shortcut for specifying a live region with aria-live=&quot;polite&quot; and aria-atomic=&quot;true&quot;. In your example above, setting aria-live=&quot;polite&quot; is superfluous since you already have role=&quot;status&quot;, 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:

&lt;div&gt;
&lt;/div&gt;

and after some user interaction, I added the following via javascript:

&lt;div&gt;
  &lt;div aria-live=&quot;polite&quot;&gt;
    I&#39;m new!
  &lt;/div&gt;
&lt;/div&gt;

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:

&lt;div aria-live=&quot;polite&quot;&gt;
&lt;/div&gt;

And then new text was added like this:

&lt;div aria-live=&quot;polite&quot;&gt;
  &lt;div&gt;
    I&#39;m new!
  &lt;/div&gt;
&lt;/div&gt;

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.

&lt;div role=&quot;status&quot; aria-live=&quot;polite&quot;&gt;{message}&lt;/div&gt;

Again, the aria-live=&quot;polite&quot; is not necessary since role=&quot;status&quot; is specified.

In my examples above, you can remove aria-live=&quot;polite&quot; and use role=&quot;status&quot; to match your code.

huangapple
  • 本文由 发表于 2023年2月16日 02:25:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/75463994.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定