是否有一个jQuery选择器来获取可以获得焦点的所有元素? [英] Is there a jQuery selector to get all elements that can get focus?

查看:109
本文介绍了是否有一个jQuery选择器来获取可以获得焦点的所有元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

解决方案

来自 OP提到的其他SO答案


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


所以,这意味着测试焦点作为元素的成员有效,因为所有元素都会拥有它,无论他们是否真正接受焦点。


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


  • HTMLAnchorElement / HTMLAreaElement,带有href
    *
    HTMLInputElement / HTMLSelectElement / HTMLTextAreaEle ment / HTMLButtonElement
    但没有禁用(如果你尝试,IE实际上会给你一个错误),
    和文件上传出于安全原因有异常行为

  • HTMLIFrameElement(虽然重点是它没有做任何有用的事情)。
    其他嵌入元素也许,我还没有测试过它们。

  • 任何带 tabindex 的元素


那么,如何在 jQuery Selector

  $(' a [href],area [href],input:not([disabled]),select:not([disabled]),textarea:not([disabled]),button:not([disabled]),iframe,object,嵌入,* [tabindex],* [contenteditable]')






更新#1



在这里更新了你的jsFiddle 。它似乎有效。



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






更新#2



As @ jfriend00指出,视使用情况而定,人们可能希望过滤掉不可见的元素。要完成此操作,只需将 .filter(':visible')应用于从上面生成的集合中选择器。






更新#3



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



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



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



这是从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&&可见(img);
}
return(/input|select|textarea |button | object /.test(nodeName)?
!element.disabled:
a=== nodeName?
element.href || isTabIndexNotNaN:
isTabIndexNotNaN)&&
//元素及其所有祖先必须是可见的
visible(element);

函数可见(元素){
返回$ .expr.filters.visible(element)&&
!$(element).parents()。addBack()。filter(function(){
return $ .css(this,visibility)===hidden;
})。长度;
}
}

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


This answer tells which HTML elements can receive focus. Is there a jQuery selector that matches exactly these elements?

For now I'm just using $('input,select,textarea,a'), but I wonder if there's something more precise.

解决方案

From the other SO answer referred to by the OP:

Today's browsers define focus() on HTMLElement, ...

So, this means testing for focus as a member of the element is not effective, because all elements will have it, regardless of whether they actually accept focus or not.

...but an element won't actually take focus unless it's one of:

  • HTMLAnchorElement/HTMLAreaElement with an href * HTMLInputElement/HTMLSelectElement/HTMLTextAreaElement/HTMLButtonElement but not with disabled (IE actually gives you an error if you try), and file uploads have unusual behaviour for security reasons
  • HTMLIFrameElement (though focusing it doesn't do anything useful). Other embedding elements also, maybe, I haven't tested them all.
  • Any element with a tabindex

So, what about naming all those explicitly in a jQuery Selector?

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


Update #1:

I updated your jsFiddle here. It appears to work.

I also added elements with attribute contenteditable to the list above.


Update #2:

As @jfriend00 pointed out, "Depending upon the use, one may want to filter out elements that aren't visible". To accomplish this, simply apply .filter(':visible') to the set generated from the above selector.


Update #3:

As Xavin pointed out: jQuery UI now has a selector, :focusable, that performs this function. If you're already using jQuery UI, this might be the way to go. If not, then you might want to check out how jQuery UI does it. In any case, the description on jQuery UI's page for :focusable is helpful:

Elements of the following type are focusable if they are not disabled: input, select, textarea, button, and object. Anchors are focusable if they have an href or tabindex attribute. area elements are focusable if they are inside a named map, have an href attribute, and there is a visible image using the map. All other elements are focusable based solely on their tabindex attribute and visibility.

So, the selector I proposed above is close, but it fails to account for a few nuances.

Here's the function ripped from jQuery UI, with minor adaptations to make it self-contained. (the adaptations are untested, but should work):

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;
    }
}

Note: the above function still depends on jQuery, but should not require jQuery UI.

这篇关于是否有一个jQuery选择器来获取可以获得焦点的所有元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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