我怎样才能得到 NVDA 和类似的读出 aria-label 和 <foreignobject> 的内容?

How can I get NVDA and similar to read out aria-label AND content of <foreignobject>?

我有一个 SVG 树形图形,我想让 NVDA 和类似的用户可以访问它。

SVG图形中的每个节点编码如下:

<g class="node" >
<foreignObject tabindex="0" focusable="true" aria-label="I want this read by screen readers such as NVDA..." class="nodestyle">...and I'd like this read out as well.</foreignObject>
</g>

当我切换到每个节点时,Chrome 只读出 foreignobject 中的文本,而 Edge Chromium 只读出 g 中的 aria-label 文本。 我试过在 g 和 foreignobject 中使用标题、标签等,但我无法让任何一个浏览器读出 both 段文本。谁能建议我如何实现这一点,如果可能的话?

我不想做一些棘手的事情,比如输入额外的文本然后用 CSS 隐藏它。

我一直在做一些非常相似的事情,尽管我没有任何 open/close hide/show 行为。

这在很大程度上不是已解决的问题,所以我很好奇在这个 space 中所做的任何工作,我希望你准备好进行进一步的通信!检查 this article. I think it's part of any proper solution. This one 也值得一看。

我尝试了很多东西,还选择了带有外国 object 的 SVG,并使用 Tab 键进行导航。甚至实施了几种不同的机制来选择分支。

棘手的事情是选择分支。有一个名为 aria-flowto 的属性,它采用一个或多个 'destination' id 作为值,但它的支持很差,并且没有推荐的习语供您选择。 (但是,它可以与 javascript 一起使用)。

我的一个尝试是使用 javaScript 将框中的内容复制到 aria-label 中,该 aria-label 附加到带有 tabindex=0 的元素上。这工作得很好,但没有提供 'browsable' 内容的任何功能。同样,宣布分支机构是一个挑战。

如果您希望使用标题等语义可供浏览 foreignObject 中的标记,您可能必须使用 role=document,许多 a11y 社区成员无疑会警告您不要这样做,因为它很棘手.我已经能够让 role=document 在 HTML 中正常工作,但尚未将其与 SVG 集成。我还不知道它是否适合 WAI-ARIA Graphics Module 角色。

遗憾的是,对于您的示例,这将很难实现(不是标签部分,而是由于文档结构而导致的一般可访问性)。

您需要做的第一件事是修复 SVG 的 DOM 顺序 - 您登陆的第一个节点是 'no' 这令人困惑,修复 DOM 顺序是比尝试管理 tabindex.

容易得多

接下来你需要证明激活一个项目(即'yes')具有加载更多选项的效果。

为此,我将遵循可折叠内容的惯例 - this accordion example 应该可以帮助您理解如何正确使用 aria-expandedaria-controls。 (但仅用于理解这些概念,它不是解决您问题的正确方法。)

接下来您需要考虑让用户知道现在向他们提供了哪些选项。最简单的方法是将 SVGs 包裹在 <ul> 中,然后屏幕 reader 将让他们知道有多少项目可供选择(在扩展部分内)。

考虑到这一点,您应该研究 treeview is structured 如何构建复杂的嵌套结构,因为这将为您提供最接近的示例。

另请参阅 this file explorer tree view example,这与看到正确嵌套后您无需担心标签过多有关。 (因为如果您发现纯文本没有正确读出,您可以使用 SVGs<title> 属性 作为内容)。

在上面的示例中您会注意到 'parent node' 文本实际上包含在 <li role="treeitem"> 中,因此当您 select 一个子项时,它会同时读取父项和 selected 项目自动一起输出。

尝试仅使用 SVG 来完成上述所有操作会给您带来许多变通方法的麻烦(即您可以使用 aria-labelledby 和子项上的多个 ID 来实现您最初的要求,但是您有很多可维护性问题)所以我建议考虑尝试复制 treeview 结构并保持 SVG 简单。

treeview方法的最后一个优点是用户将熟悉如何控制树视图(箭头键和space 以展开/折叠),因此您无需尝试教育他们使用什么控件。

例子

有点难读,但希望能让您了解最终结构应该是什么样子。我已经删除了很多定位属性等,以使其更易于阅读。

<h3 id="tree_lbl">
  Decision Tree
</h3>
<ul role="tree" aria-labelledby="tree_lbl">
  <li role="treeitem" aria-expanded="false">
      <g class="node">
        <foreignObject tabindex="0" focusable="true" class="nodestyle">Is this a decision tree?</foreignObject>
      </g>
    <ul role="group">
      <li role="treeitem" aria-expanded="false">
        <g class="node">
          <foreignObject tabindex="0" focusable="true" class="nodestyle">Yes</foreignObject>
        </g>
        <ul role="group">
          <li role="treeitem">
            <g class="node"><foreignObject tabindex="0" focusable="true" class="nodestyle">A</foreignObject></g>
          </li>
          <li role="treeitem">
            <g class="node">
              <foreignObject tabindex="0" focusable="true" class="nodestyle">B</foreignObject>
            </g>
          </li>
        </ul>
      </li>
      <li role="treeitem" aria-expanded="false">
        <span>
          <g class="node">
              <foreignObject tabindex="0" focusable="true" class="nodestyle">No</foreignObject></g>
        </span>
        <ul role="group">
          <li role="treeitem" class="doc">
            <g class="node">
              <foreignObject tabindex="0" focusable="true" class="nodestyle">A1</foreignObject>
            </g>
          </li>
          <li role="treeitem" class="doc">
            <g class="node">
              <foreignObject tabindex="0" focusable="true" class="nodestyle">B1</foreignObject>
            </g>
          </li>
        </ul>
      </li>
    </ul>
  </li>
  </ul>