10

我想使用当前的 Web 组件规范实现一个列表框小部件。此外,生成的列表框应符合 ARIA 标准。实例化列表框小部件应该很简单:

<x-listbox>
    <x-option>Option 1</x-option>
    <x-option>Option 2</x-option>
</x-listbox>

出于清洁和封装的目的,其他一切都应该在 shadow dom 中渲染。为了实现这个小部件,注册了两个自定义<x-listbox>元素<x-option>。shadow dom 的顶级元素<x-listbox>是 a <div>,它带有role=listboxaria-activedescendent可访问性的属性(我不希望<x-listbox>元素上有这些属性,因为它们是实现细节。)

为了aria-activedescendent工作,需要选项元素上的 id。将 id 直接放在<x-option>元素上不会起作用,原因有两个:首先,它会污染使用列表框小部件的文档的 id 命名空间。其次,更重要的是,id 不能跨影子边界工作(这是影子 dom 的目的之一),因此选项的 id 必须<div>aria-activedescendent属性位于相同的影子 dom 中。

一个解决方案是用另一个(属于那个shadow dom)包围<x-option>作为内容呈现在shadow dom中的每个,在其上可以放置一个id。<x-listbox><div>

我的问题是:这是正确的方法吗?如何使用自定义元素和 shadow dom web api 来实现它?

4

2 回答 2

1

您可能应该通过创建一个select元素(使用 JavaScript)来更好地实现这一点。这应确保屏幕阅读器将其正确识别为从列表中选择值的输入。

在您的元素下方添加select这样的<x-listbox>元素:

<select class="only-screenreader">
   <option>Option 1</option>
   <option>Option 2</option>
</select>

然后添加aria-hidden="true"到您的自定义<x-listbox>元素。

最后应用 CSS 使屏幕阅读器选择元素不可见。

.only-screenreader {
   position:absolute;
   left:-10000px;
   top:auto;
   width:1px;
   height:1px;
   overflow:hidden;
}

这是我的方法,但也许有更好的方法。

于 2014-08-17T18:26:56.280 回答
0

在提供的标记中,x-option是在 light DOM 中,而不是在 shadow DOM 中,所以可以通过 id 来引用。为了避免污染 id 命名空间,我生成了一个随机的 id,该 id 是在组件加载时设置但可以替换的。这样,无论组件用户是否在其上设置了 id,我都可以通过 id 引用元素。将每个选项包装在 a 中div似乎是不必要的,并且可能会导致问题。此外,如果选项在 a 中<slot />,那根本不可能。

于 2021-05-25T13:47:22.873 回答