Ответ 1
Из другого ответа SO, на который ссылается OP:
Сегодня браузеры определяют focus() на HTMLElement,...
Итак, это означает, что тестирование для 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:
I обновил jsFiddle здесь. Кажется, что он работает.
Я также добавил элементы с атрибутом contenteditable
в список выше.
Обновление # 2:
Как заметил @jfriend00: "В зависимости от использования, вы можете отфильтровать элементы, которые не видны". Чтобы выполнить это, просто примените . Filter (': visible') к набору, сгенерированному из указанного выше селектора.
Обновление # 3:
Как Xavin указал: jQuery UI теперь имеет селектор, : focusable, который выполняет эту функцию. Если вы уже используете jQuery UI, это может быть путь. Если нет, то вы можете захотеть проверить, как работает jQuery UI. В любом случае полезно использовать описание на странице пользовательского интерфейса jQuery для :focusable
:
Элементы следующего типа могут быть сфокусированы, если они не отключены: ввод, выбор, текстовое поле, кнопка и объект. Якорями можно сфокусировать, если они имеют атрибут href или tabindex. элементы области могут быть сфокусированы, если они находятся внутри именованной карты, имеют атрибут href, и на карте отображается видимое изображение. Все остальные элементы настраиваются только на основе атрибута tabindex и видимости.
Итак, селектор, который я предложил выше, близок, но он не учитывает несколько нюансов.
Здесь функция ripped из 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.