我想使用当前的网络组件规范来实现一个列表框小部件。此外,生成的列表框应符合ARIA标准。实例化列表框小部件应该简单如下:
<x-listbox>
<x-option>Option 1</x-option>
<x-option>Option 2</x-option>
</x-listbox>
为了清洁和封装,其他一切都应该用阴影dom渲染。要实现此窗口小部件,需要注册两个自定义元素<x-listbox>
和<x-option>
。 <x-listbox>
影子dom的顶级元素是<div>
,其中包含role=listbox
和aria-activedescendent
属性以便访问(我不想要这些属性)在<x-listbox>
元素上,因为它们是实现细节。)
为了使aria-activedescendent
起作用,需要选项元素的ID。将id直接放在<x-option>
元素上的原因有两个:第一,它会污染使用列表框小部件的文档的id命名空间。其次,更重要的是,id不能跨越阴影边界(这是阴影dom的一个目的),因此选项的id必须与<div>
一样生成与{{1}相同的阴影dom属性。
对此的一个解决方案是围绕aria-activedescendent
的阴影dom内的每个<x-option>
包围另一个<x-listbox>
(属于该阴影dom),其中id可以放。
我的问题是:这是正确的方法吗?如何使用自定义元素和影子dom web apis实现这一点?
答案 0 :(得分: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;
}
这是我的方法,但也许有更好的方法。
答案 1 :(得分:0)
在提供的标记中,x-option
位于 light DOM 中,而不是 shadow DOM 中,因此可以通过 id 引用它。为了避免污染 id 命名空间,我生成了一个随机 id,该 id 在组件加载时设置但可以替换。这样我就可以通过 id 引用元素,无论组件用户是否在其上设置了 id。
将每个选项包装在 div
中似乎没有必要,而且可能会导致问题。此外,如果选项位于 <slot />
中,则根本不可能。