最简单的方法只能通过特定元素的可聚焦后裔制表? [英] Simplest way to tab only through focusable descendants of a particular element?

查看:103
本文介绍了最简单的方法只能通过特定元素的可聚焦后裔制表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个充满可聚焦元素的文档,要么是因为它们天生就是可以聚焦的(比如< input type =text> ), tabindex =0之类的。



现在让我们来说说我想要的文档的一部分显示为模式对话框,我不希望用户被对话框外的任何东西分心。我希望tab键只能通过对话框的容器元素内的可聚焦元素循环。什么是最简单的方法来做到这一点?

如果可能的话,我正在寻找一个解决方案,不关心对话框的内容或页面的其余部分是和不会尝试修改它们。也就是说,例如,我不想让对话框外的元素不可聚焦。首先,这需要做出可逆的变化,并追踪状态。其次,这需要知道一个元素可以被聚焦的所有可能的方式。这感觉凌乱,脆弱,无法对我。



我的第一次尝试看起来像这样,但只能在向前的方向(按Tab键)。它不能在反方向工作(按住Shift + Tab键)。

 < div>可对焦的内容。 < / DIV> 
< div class =dialogtabindex =0>
<! - 焦点应该在打开的时候被困在这个对话框中 - >
< div class =content>
在这里表达内容和可聚焦的东西。
< / div>
< div class =last-focustabindex =0onfocus =this.parentNode.focus()>< / div>
< / div>
< div>对话框外部的可聚焦内容。< / div>

我宁愿看纯JavaScript解决方案。如果有这样的一个库,如jQuery这样做,我宁愿链接到库代码,这样做。

为了完整起见,我将链接指向 jQuery UI对话框,由@Domenic提供并填写详细信息。

为了实现这个jQuery时尚需要两个事情:
$ b


  1. 听取标签 Shift + Tab (在 keydown ),以便应该捕捉焦点的模态元素。这是通过键盘移动焦点的唯一手段。 (如果要防止鼠标与文档的其余部分交互,这是一个单独的问题,通过覆盖元素来解决,以防止任何鼠标事件通过。)


  2. 找到模态元素中的所有可放置元素。这些是所有可聚焦元素的子集,不包括那些具有 tabindex = - 1


Tab 前进。 Shift + Tab 往后退。任何时候按下 Tab键,当模态元素中的最后一个tabbable元素被关注时,第一个应该获得焦点。同样的,任何时候 Shift + Tab 都会在第一个tabbable元素被关注的时候被按下,最后一个应该会获得焦点。这将保持焦点内的模态元素。



困难的部分是知道哪些元素是可tabbable。因为tabbable元素都是没有 tabindex = - 1的可聚焦元素,所以我们需要知道哪些元素是可聚焦的。由于没有属性来确定元素是否可以聚焦,jQuery通过对以下情况进行硬编码


  • 输入 select textarea 按钮元素

  • a 区域具有 href 的元素,或者为 tabindex set设置一个数值。

  • 具有 tabindex set的数值的任何元素。



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


  • 没有祖先是 display:none
  • visibility 的计算值是 visible 。这意味着具有 visibility 集合的最近的祖先必须具有 visible 的值。如果没有祖先的 visibility set,那么计算的值是 visible

  • ul>

    需要注意的是, jQuery的:visible 选择器对于这个实现看起来不正确,因为它表示具有 visibility:hidden ...的元素被认为是可见的,但它们不是可以调整的。


    Let's say I have a document full of focusable elements, either because they are innately focusable (like <input type="text">) or because they have tabindex="0" or the like.

    Now let's say there's a section of my document that I want to display as a modal dialog box, and I don't want the user to be distracted by anything outside the dialog box. I would like for the tab key to cycle only through focusable elements inside the container element for the dialog box. What is the simplest way to do this?

    If possible, I am looking for a solution that doesn't care what the contents of the dialog or the rest of the page are and doesn't try to modify them. That is, I don't want to make the elements outside of the dialog not focusable, for example. First, this requires making a reversible change and keeping track of state. Second, this requires knowing all the possible ways an element could be made focusable. This feels messy, fragile, and unscalable to me.

    My first attempt looks like this, but works only in the forward direction (pressing Tab). It doesn't work in the reverse direction (pressing 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>
    

    I'd rather see pure JavaScript solutions. If there is a means of doing this with a library such as jQuery, I would prefer a link to the library code that does this.

    解决方案

    In the interest of completeness, I'm taking the link to jQuery UI dialog that @Domenic provided and filling in the details.

    To implement this in the jQuery fashion requires two things:

    1. Listening for Tab or Shift+Tab (on keydown) for the modal element that should trap focus. This is the only means of moving focus via the keyboard. (If you want to prevent mouse interaction with the rest of the document, that is a separate problem solved by covering it with an element to prevent any mouse events from getting through.)

    2. Finding all tabbable elements inside the modal element. These are a subset of all focusable elements, excluding those that have tabindex="-1".

    Tab goes forward. Shift+Tab goes backwards. Any time Tab is pressed while the last tabbable element in the modal element is focused, the first should receive focus. Similarly, any time Shift+Tab is pressed while the first tabbable element is focused, the last should receive focus. This will keep focus inside the modal element.

    The hard part is knowing which elements are tabbable. Since tabbable elements are all focusable elements that don't have tabindex="-1", then we need to know know which elements are focusable. Since there's no property to determine if an element is focusable, jQuery does it by hard-coding the following cases:

    • input, select, textarea, button, and object elements that aren't disabled.
    • a and area elements that have an href or have a numerical value for tabindex set.
    • any element that has a numerical value for tabindex set.

    It's not enough to check for these three cases. jQuery goes on to ensure that the element is visible. This means both of the following must be true:

    • None of its ancestors are display: none.
    • The computed value of visibility is visible. This means that the nearest ancestor to have visibility set must have a value of visible. If no ancestor has visibility set, then the computed value is visible.

    It should be noted that jQuery's :visible selector does not look correct for this implementation because it says "elements with visibility: hidden…are considered to be visible," but they are not focusable.

    这篇关于最简单的方法只能通过特定元素的可聚焦后裔制表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆