是否有一个jQuery选择器来获取可以获得焦点的所有元素?

rip*_*234 27 javascript jquery

这个答案告诉哪些HTML元素可以获得焦点.是否有一个jQuery选择器完全匹配这些元素?

现在我只是在使用$('input,select,textarea,a'),但我想知道是否有更精确的东西.

Lee*_*Lee 32

来自OP提到另一个SO回答:

今天的浏览器在HTMLElement上定义focus(),...

因此,这意味着测试focus作为元素的一员是不是有效的,因为所有的元素都会有它,无论他们是否真正接受焦点.

...但是除非是下列之一,否则元素实际上不会成为焦点:

  • 带有href*HTMLInputElement/HTMLSelectElement/HTMLTextAreaElement/HTMLButtonElement但没有的HTMLAnchorElement/HTMLAreaElement disabled(如果你尝试,IE实际上会给你一个错误),并且出于安全原因,文件上传有异常行为
  • HTMLIFrameElement(虽然重点是它没有做任何有用的事情).其他嵌入元素也许,我还没有测试过它们.
  • 任何有元素的元素 tabindex

那么,如何在jQuery Selector中明确命名所有这些呢?

$('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]')
Run Code Online (Sandbox Code Playgroud)

更新#1:

在这里更新了你的jsFiddle.它似乎工作.

我还在contenteditable上面的列表中添加了带属性的元素.


更新#2:

正如@jfriend00指出的那样,"根据用途,人们可能想要过滤掉不可见的元素".要完成此操作,只需将.filter(':visible')应用于从上面的选择器生成的集合.


更新#3:

正如Xavin指出的那样:jQuery UI现在有一个执行此功能的选择器:focusable.如果您已经在使用jQuery UI,那么这可能就是您的选择.如果没有,那么你可能想看看jQuery UI如何做到这一点.在任何情况下,jQuery UI页面上的描述:focusable都是有帮助的:

如果未禁用以下类型的元素,则可以对其进行聚焦:输入,选择,文本区域,按钮和对象.如果锚具有href或tabindex属性,则它们是可聚焦的.如果区域元素位于命名地图内部,具有href属性,并且使用地图存在可见图像,则它们是可聚焦的.所有其他元素都可以根据其tabindex属性和可见性进行聚焦.

所以,我上面提出的选择器很接近,但它没有考虑到一些细微差别.

这是从jQuery UI中删除的功能,通过微小的调整使其自包含.(改编是未经测试的,但应该有效):

function focusable( element ) {
    var map, mapName, img,
        nodeName = element.nodeName.toLowerCase(),
        isTabIndexNotNaN = !isNaN( $.attr( element, "tabindex" ) );
    if ( "area" === nodeName ) {
        map = element.parentNode;
        mapName = map.name;
        if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
            return false;
        }
        img = $( "img[usemap=#" + mapName + "]" )[0];
        return !!img && visible( img );
    }
    return ( /input|select|textarea|button|object/.test( nodeName ) ?
        !element.disabled :
        "a" === nodeName ?
            element.href || isTabIndexNotNaN :
            isTabIndexNotNaN) &&
        // the element and all of its ancestors must be visible
        visible( element );

    function visible( element ) {
      return $.expr.filters.visible( element ) &&
        !$( element ).parents().addBack().filter(function() {
          return $.css( this, "visibility" ) === "hidden";
        }).length;
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:上面的函数仍然依赖于jQuery,但不应该需要jQuery UI.

  • JQUI 中的当前实现很好且独立:https://github.com/jquery/jquery-ui/blob/master/ui/focusable.js (2认同)
  • 伙计们不要忘记`:not([tabindex=-1])`。它在技术上是可聚焦的,但无法通过选项卡访问。 (2认同)

Gus*_*Gus 5

您可以检查具有该focus()功能的元素:

$('*').each(function() {
  if(typeof this.focus == 'function') {
    // Do something with this element
  }
}) ;
Run Code Online (Sandbox Code Playgroud)

编辑 思考一下,对于大多数应用程序来说,拥有*:visible而不仅仅是*选择器可能是有意义的.


tzi*_*tzi 5

另一个简单但完整的jQuery选择器可能就是这个:

$('a[href], area[href], input, select, textarea, button, iframe, object, embed, *[tabindex], *[contenteditable]')
.not('[tabindex=-1], [disabled], :hidden')
Run Code Online (Sandbox Code Playgroud)

  • [tabtab]前面的*是不必要的 (2认同)