javascript 仅通过特定元素的可聚焦后代切换的最简单方法?

vuv7lop3  于 2023-01-16  发布在  Java
关注(0)|答案(3)|浏览(146)

假设我有一个充满可聚焦元素的文档,或者因为它们天生就可聚焦(如<input type="text">),或者因为它们具有tabindex="0"等。
现在,假设我想将文档的某个部分显示为模态对话框,并且我不希望用户被对话框之外的任何内容分散注意力。我希望Tab键只在对话框的容器元素内的可聚焦元素之间循环。最简单的方法是什么?
如果可能的话,我正在寻找一个解决方案,它不关心对话框或页面其余部分的内容是什么,也不试图修改它们。也就是说,我不想让对话框以外的元素不可聚焦。首先,这需要进行可逆的更改并跟踪状态。其次,这需要知道所有可能的方法,一个元素可以被聚焦。2这让我感觉混乱,脆弱,不可扩展。
我的第一次尝试看起来是这样的,但只在正向(按Tab键)工作,在反向(按Shift+Tab键)不工作。

<div>Focusable stuff outside the dialog.</div>
<div class="dialog" tabindex="0">
  <!-- Focus should be trapped inside this dialog while it's open -->
  <div class="content">
    Form contents and focusable stuff here.
  </div>
  <div class="last-focus" tabindex="0" onfocus="this.parentNode.focus()"></div>
</div>
<div>More focusable stuff outside the dialog.</div>

我更愿意看到纯JavaScript的解决方案,如果有一种方法可以用jQuery这样的库来实现,我更愿意看到一个链接到实现这一点的库代码。

pu82cl6c

pu82cl6c1#

为了完整起见,我将使用@Domenic提供的jQuery UI对话框的链接并填写详细信息。
要以jQuery方式实现这一点,需要做两件事:
1.监听TabShift+Tab(在keydown上)中应该捕获焦点的模态元素。这是通过键盘移动焦点的唯一方法。(如果你想防止鼠标与文档的其余部分交互,这是一个单独的问题,可以用一个元素覆盖它,以防止任何鼠标事件通过。)
1.查找模态元素中的所有可制表元素。这些元素是所有可聚焦元素的子集,不包括具有tabindex="-1"的元素。
Tab前进。Shift+Tab后退。当模态元素中的最后一个可选项卡元素获得焦点时,按下Tab的任何时间,第一个可选项卡元素应获得焦点。类似地,当第一个可选项卡元素获得焦点时,按下Shift+Tab的任何时间,最后一个可选项卡元素应获得焦点。这将使焦点保持在模态元素内。
困难的部分是知道哪些元素是可制表的。由于可制表元素都是没有tabindex="-1"的可聚焦元素,那么我们需要知道哪些元素是可聚焦的。由于没有属性来确定元素是否是可聚焦的,jQuery通过hard-coding the following cases来完成:

  • 未禁用的inputselecttextareabuttonobject元素。
  • aarea元素,这些元素具有href集合或具有tabindex的数值集合。
  • 设置了tabindex数值的任何元素。

仅仅检查这三种情况是不够的,jQuery会继续检查以确保元素可见,这意味着以下两个条件都必须为真:

  • 它的祖先都不是display: none
  • visibility的计算值为visible。这意味着设置了visibility的最近祖先必须具有visible的值。如果没有设置了visibility的祖先,则计算值为visible

应该注意的是,jQuery's :visible selector在这个实现中看起来并不正确,因为它说“具有visibility: hidden的元素......被认为是可见的”,但是它们是不可聚焦的。

wixjitnu

wixjitnu2#

jQueryUI对话框通过捕获keydown事件,检查它们是否用于TAB,然后手动聚焦正确的元素来完成此操作。

nhhxz33t

nhhxz33t3#

jqModal jQuery插件通过将modal选项设置为true来实现这一点。本页上的表单示例应该显示了这一点。我记得我查看了代码,看看发生了什么,你可以很容易地用普通JS完成这一点。

相关问题