javascript 是否有一个 jQuery 选择器来获取所有可以获得焦点的元素?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7668525/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a jQuery selector to get all elements that can get focus?
提问by ripper234
This answertells which HTML elements can receive focus. Is there a jQuery selector that matches exactly these elements?
这个答案告诉了哪些 HTML 元素可以接收焦点。是否有与这些元素完全匹配的 jQuery 选择器?
For now I'm just using $('input,select,textarea,a')
, but I wonder if there's something more precise.
现在我只是使用$('input,select,textarea,a')
,但我想知道是否有更精确的东西。
回答by Lee
From the other SO answer referred to by the OP:
Today's browsers define focus() on HTMLElement, ...
今天的浏览器在 HTMLElement 上定义了 focus(),...
So, this means testing for focus
as a member of the element is noteffective, because allelements will have it, regardless of whether they actually accept focus or not.
所以,这种测试手段对focus
作为元素的一员是不是有效的,因为所有的元素都会有它,无论他们是否真正接受焦点。
...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
...但一个元素实际上不会成为焦点,除非它是以下之一:
- HTMLAnchorElement/HTMLAreaElement 带有一个 href * HTMLInputElement/HTMLSelectElement/HTMLTextAreaElement/HTMLButtonElement 但不带有
disabled
(如果你尝试,IE 实际上会给你一个错误),并且出于安全原因,文件上传有异常行为- HTMLIFrameElement (虽然聚焦它并没有做任何有用的事情)。其他嵌入元素也可能,我还没有全部测试过。
- 任何带有
tabindex
So, what about naming all those explicitly in a jQuery Selector?
那么,如何在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:
更新#1:
I updated your jsFiddle here. It appears to work.
我在这里更新了你的 jsFiddle。它似乎有效。
I also added elements with attribute contenteditable
to the list above.
我还在contenteditable
上面的列表中添加了具有属性的元素。
Update #2:
更新#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.
正如@jfriend00 指出的那样,“根据使用情况,人们可能希望过滤掉不可见的元素”。为此,只需将.filter(':visible')应用于从上述选择器生成的集合。
Update #3:
更新 #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:
正如Xavin 指出的那样:jQuery UI 现在有一个选择器:focusable来执行这个功能。如果您已经在使用 jQuery UI,那么这可能是您要走的路。如果没有,那么您可能想看看 jQuery UI 是如何做到的。无论如何,jQuery UI 页面上的描述:focusable
是有帮助的:
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.
如果未禁用以下类型的元素,则它们是可聚焦的:输入、选择、文本区域、按钮和对象。如果锚具有 href 或 tabindex 属性,则它们是可聚焦的。如果 area 元素位于命名地图内、具有 href 属性并且有使用地图的可见图像,则它们是可聚焦的。所有其他元素都可以仅根据它们的 tabindex 属性和可见性来聚焦。
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):
这是从 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;
}
}
Note: the above function still depends on jQuery, but should not require jQuery UI.
注意:上述函数仍然依赖于 jQuery,但应该不需要 jQuery UI。
回答by tzi
Another simple, but complete, jQuery selector could be this one:
另一个简单但完整的 jQuery 选择器可能是这样的:
$('a[href], area[href], input, select, textarea, button, iframe, object, embed, *[tabindex], *[contenteditable]')
.not('[tabindex=-1], [disabled], :hidden')
回答by Gus
You could check for elements that have the focus()
function:
您可以检查具有以下focus()
功能的元素:
$('*').each(function() {
if(typeof this.focus == 'function') {
// Do something with this element
}
}) ;
EditThinking a little more, it would probably makes sense to have *:visible
rather than just *
as the selector for most applications of this.
再想一想,对于大多数应用程序来说,拥有*:visible
而不是仅仅*
作为选择器可能更有意义。
回答by Adam Leggett
I have a relatively simple solution that returns all tabbable children, in their tab order, without using jQuery.
我有一个相对简单的解决方案,它在不使用 jQuery 的情况下,按 Tab 键顺序返回所有可制表的子项。
function tabbable(el) {
return [].map.call(el.querySelectorAll([
'input',
'select',
'a[href]',
'textarea',
'button',
'[tabindex]'
]), function(el, i) { return { el, i } }).
filter(function(e) {
return e.el.tabIndex >= 0 && !e.el.disabled && e.el.offsetParent; }).
sort(function(a,b) {
return a.el.tabIndex === b.el.tabIndex ? a.i - b.i : (a.el.tabIndex || 9E9) - (b.el.tabIndex || 9E9); });
}
For IE, consider implementing a different visibility check than e.el.offsetParent
. jQuery can help you here.
对于 IE,请考虑实施与e.el.offsetParent
. jQuery 可以在这里为您提供帮助。
If you don't need the elements sorted, leave out the call to sort()
.
如果您不需要对元素进行排序,请省略对 的调用sort()
。
回答by Xavin
In jQuery not exists the selector you're finding.
在 jQuery 中不存在您正在查找的选择器。
If you're already using jQueryUI, you can use :focusableselector.
如果您已经在使用 jQueryUI,则可以使用:focusable选择器。
回答by Dennis
Instead of getting a list of focusable elements, you may want to try setting up a focus handler at the body
element that captures focus events.
您可能想要尝试在body
捕获焦点事件的元素上设置焦点处理程序,而不是获取可聚焦元素的列表。
$(document.body).on("focus", "*", function(e) {
//Scroll to e.target
});
回答by Mariusz Charczuk
var allElementsThatCanBeFocused = $(':focusable');
回答by RobG
A general test to know whether an element supports a particular type of listener is to see if it has a related property, e.g. to test for support for the focusevent, use:
了解元素是否支持特定类型的侦听器的一般测试是查看它是否具有相关属性,例如测试是否支持焦点事件,请使用:
if ('focus' in element) {
// element supports the focus event
}
However, there are some exceptions. See the answers to How do you programmatically determine to which events an HTML object can listen for?.
但是,也有一些例外。请参阅如何以编程方式确定 HTML 对象可以侦听哪些事件的答案?.