This answer告诉哪些HTML元素可以获得焦点。有没有一个jQuery选择器完全匹配这些元素?是否有一个jQuery选择器来获取所有可以获得焦点的元素?
现在我只是使用$('input,select,textarea,a')
,但我不知道是否有更精确的东西。
This answer告诉哪些HTML元素可以获得焦点。有没有一个jQuery选择器完全匹配这些元素?是否有一个jQuery选择器来获取所有可以获得焦点的元素?
现在我只是使用$('input,select,textarea,a')
,但我不知道是否有更精确的东西。
你可以检查该有focus()
功能要素:
$('*').each(function() {
if(typeof this.focus == 'function') {
// Do something with this element
}
}) ;
编辑 思考多一点,它可能会很有意义的*:visible
而不仅仅是*
的选择对于大多数应用这个。
绝对要走的路。因为jQuery选择器是建立在http://sizzlejs.com上的,所以我认为就显式选择器而言,这是不可能的。 – ifightcrime
除了,如果你阅读链接在OP中的帖子,它说:“只有具有focus()方法的元素是HTMLInputElement,HTMLSelectElement,HTMLTextAreaElement和HTMLAnchorElement。这明显地省略了HTMLButtonElement和HTMLAreaElement.'所以测试'.focus()'不会(明显地)执行它。 – Lee
DOM元素是主机对象,它们不需要符合ECMAScript的规则,因此它们对* typeof *运算符的响应可以是任何内容,包括抛出错误。在IE 8中,'typeof element.focus'在文本输入上返回* object *,所以上面的测试在大约1:5的浏览器中使用时会失败,可能更多。 – RobG
从other SO answer referred to by the OP:
今天的浏览器定义焦点()在HTML元素,...
因此,这意味着focus
测试作为元素的成员是不有效,因为所有的元素都会拥有它,无论他们是否真的接受焦点。
...但一个元素不会采取实际的重点,除非它的一个:
- HTMLAnchorElement/HTMLAreaElement带有href * HTMLInputElement/HTMLSelectElement/HTMLTextAreaElement/HTMLButtonElement 但与
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]')
更新#1:
我updated your jsFiddle here。它似乎工作。
我还在上面的列表中添加了属性为contenteditable
的元素。
更新#2:
正如@ jfriend00指出, “根据不同的用途,一个可能要过滤掉不可见元素”。要做到这一点,只需将.filter(':visible')应用于上述选择器生成的集合。
更新#3:
作为Xavin pointed out:jQuery用户界面现在有一个选择器,:focusable,执行此功能。如果你已经在使用jQuery UI,这可能是一条可行的路。如果没有,那么你可能想要check out how jQuery UI does it。在任何情况下,:focusable
jQuery的UI页面上的说明是有帮助的:
以下类型的元素是可聚焦的,如果他们没有被禁用:输入,选择,文本区域,按钮和对象。如果锚点具有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;
}
}
注:以上功能仍取决于jQuery的,但不应该要求jQuery UI的。
知道元素是否支持特定类型的侦听器的一般测试是看它是否具有相关属性,例如,测试支持为重点事件,使用:
if ('focus' in element) {
// element supports the focus event
}
不过,也有一些例外。请参阅How do you programmatically determine to which events an HTML object can listen for?的答案。
您可能想要尝试在捕获焦点事件的body
元素上设置焦点处理程序,而不是获取可聚焦元素的列表。
$(document.body).on("focus", "*", function(e) {
//Scroll to e.target
});
除了我们已经证明检查'this.focus'的类型不起作用。 – jfriend00
在jQuery中不存在您正在查找的选择器。
如果您已经使用jQueryUI,则可以使用:focusable选择器。
我有一个相对简单的解决方案,它返回所有tabbable的孩子,在他们的标签顺序,无需使用jQuery。
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); });
}
对于IE,考虑实施与e.el.offsetParent
不同的可见性检查。 jQuery可以帮助你。
如果您不需要排序元素,请拨打电话sort()
。
可能不是。也许试试[':input'](http://api.jquery.com/input-selector/)选择器? – Bojangles
一旦你有可聚焦元素的列表,你想做什么? – Dennis
@丹尼斯 - 向下滚动以确保它们在聚焦时可见。 http://stackoverflow.com/questions/7650892/how-to-scroll-down-the-page-when-a-covered-input-box-is-focused – ripper234