如何使 div 及其所有后代无法聚焦
Posted
技术标签:
【中文标题】如何使 div 及其所有后代无法聚焦【英文标题】:How to make a div and all its descendants unfocusable 【发布时间】:2022-01-23 02:44:43 【问题描述】:我试图让一个 div 及其所有后代无法聚焦。我在根 div 上使用了 tabIndex -1。但这使焦点转移到了它的第一个可聚焦的孩子身上。 (默认行为)是否有解决此问题的方法?
示例代码
const SomeFunctionComponent = () =>
// ... some logic ...
const someTrustedhtml = `<p>Hello <a href="***.com">World!</a></p>`;
const content = React.createElement("div",
className: "some class name",
dangerouslySetInnerHTML:
__html: someTrustedHtml;
,
tabIndex: -1, /* "tabindex": -1 does not work */
// None of these options helped either
// "data-is-focusable": false,
// "aria-hidden": true,
// disabled: true,
// role: "presentation"
);
// ... more logic ...
return (
<div>
content
<button onClick=() => console.log("hello world")></button>
/* some tab focusable elements */
</div>
);
预期行为:
当SomeFunctionComponent
获得焦点时,焦点会移动到按钮上
实际行为: 焦点转到危险的SetInnerHtml中的链接
【问题讨论】:
【参考方案1】:tabindex
不可继承。您必须在每个原生可聚焦的元素上设置它。
有趣的是,规范说将其设置为 -1 不会不会导致元素不可聚焦,但我一直使用它,它适用于所有浏览器。
请注意,tabindex 属性不能用于使元素不可聚焦。页面作者可以做到这一点的唯一方法是禁用该元素,或使其变为惰性。
【讨论】:
【参考方案2】:没有简单的解决方案。正如另一个答案所说,您必须遍历 div 内的所有可聚焦对象。
事实上,与其在 div 内的所有可聚焦元素上设置 tabindex=-1,不如通过 display:none 或 hidden 属性完全隐藏 div,或者使用表单字段的 disabled 属性作为第二选择。 隐藏元素不可聚焦。
设置 disabled 属性对于让用户直观地看到他/她当前无法使用该字段以及告诉屏幕阅读器用户这一事实非常重要。 所以,更可取。将 disabled 属性自动设置为 true 意味着该字段不再具有焦点。
提醒一下,设置 tabindex=-1 不会使元素完全无法聚焦。 它不再允许用户使用选项卡或其他常规方式对其进行聚焦,但它仍然可以通过编程方式聚焦(使用 focus() 方法)。 请注意,使用用户脚本完全可以绕过直接无法聚焦。
【讨论】:
【参考方案3】:正如其他人所说,tabindex
不可继承。但是,焦点陷阱能否帮助您实现类似的目标,或许方式略有不同?焦点陷阱就像它们听起来的那样 - 它们将焦点保持在元素及其后代中。听起来与您尝试做的有点相反,但它可能会产生一些帮助。 https://github.com/focus-trap/focus-trap
【讨论】:
以上是关于如何使 div 及其所有后代无法聚焦的主要内容,如果未能解决你的问题,请参考以下文章