html 防止子元素成为交互式和可聚焦的

tpxzln5u  于 2022-12-02  发布在  其他
关注(0)|答案(3)|浏览(142)

我正在构建一个交互式小部件,该小部件包括从HTML标记列表中生成一个按钮列表。为了实现这一点,HTML标记被一个类似按钮的组件<div role="button" tabindex="0" aria-label="Action..."> Package 。当单击按钮时,将执行一些脚本。
我不能控制HTML子标记,我想阻止所有其他交互元素与之交互。但是,它们应该保持可见。
从鼠标用户的Angular 来看,这可以通过在所有子元素上设置pointer-events: none;来实现。
从键盘用户的Angular 来看,我需要一种方法来防止交互元素被交互。
在本例中,焦点应该从tabindex=“0”的第一个div转到tabindex=“0”的第二个div,而不是聚焦在<a>标签上。
第一个
我想到的一种实现方法是在子交互元素上设置tabindex="-1"。它将从Tab键顺序中删除这些元素。但是,它不会阻止以编程方式访问它们,例如,从屏幕阅读器链接菜单中。
我想知道是否有其他的技术可以使一个元素的所有子元素都是非交互的。特别是可以应用在 Package 器上的技术,所以没有必要找到所有的交互元素并替换它们。

lb3vh1jj

lb3vh1jj1#

In the end, you would need to assign the following:

<button aria-label="Label text … additional text">
  <div inert>
    …
    <a tabindex="-1"
       aria-hidden="true"
       style="pointer-events: none">
    …

Regarding the ARIA standard, part of this is already recommended standard behavior of button children. For the button role, it reads:
Children Presentational: True
Some roles have representational children. That is to say, they should remove any roles from their children. Hence a link would not be exposed in the link menu.
The DOM descendants are presentational. User agents SHOULD NOT expose descendants of this element through the platform accessibility API.
Unfortunately, it’s not a MUST and not implemented in browsers. So you’d need to implement that part manually.

Hiding specific roles from the screen reader menus

Usually, you’d be adding role="presentation" or role="none" to the children so that they are not presented in the generated menus anymore.
Unfortunately, this does not work if applied by a script. A link will stay exposed as a link.
What works is to hide the element entirely through aria-hidden . This will also remove it from the accessible name calculation.

Provide an accessible name for the button

Usually, the button’s name would be calculated from the texts of all children. Once you hide them all, the button is empty.
So you need to provide a name yourself with aria-label . Beware of Label in Name , though.
Many screen reader users are sighted, and to direct voice control software towards a button, the visible text needs to match at least partly with the accessible name. So the aria-label value should start with the visible text. You could, for example, provide a backdrop that renders the original contents blurry and adds that label.

Prevent user interaction

The above will not prevent user interaction directly with the children. The inert attribute on a wrapper does that, but it’s not supported everywhere yet.
[…it] makes the browser "ignore" user input events for the element, including focus events and events from assistive technologies. […]
So you can also apply tabindex="-1" as you suggested, to make sure browsers that don’t support inert don’t allow keyboard interaction.

document.querySelectorAll('button *').forEach(n => {
  n.setAttribute('inert', '');
  n.setAttribute('tabindex', '-1');
  n.setAttribute('aria-hidden', '')
});
button * {
  pointer-events: none;
}
<button>
  This should not be <a href="#" onclick="alert('damn, it‘s still a link')">a link</a>
</button>
jgzswidk

jgzswidk2#

添加tabindex="-1”和aria-hidden=“true”应该足够好了,因为元素不会向屏幕阅读器用户传达任何额外的信息。

sycxhyv7

sycxhyv73#

最简单的解决方案是给<div role="button">的第一个子元素给予inert属性。
具体来说,inert执行以下操作:

  • 防止在用户单击元素时激发click事件。
  • 通过阻止元素获得焦点来阻止引发焦点事件。
  • 通过将元素及其内容从辅助功能树中排除,对辅助技术隐藏这些元素及其内容。

但是浏览器支持不好,例如Firefox上没有支持。
为了获得更好的兼容性,解决方案是用途:

相关问题