Desde el other SO answer referred to by the OP:
navegadores de hoy definen el enfoque() en HTMLElement, ...
lo tanto, esto significa que las pruebas de focus
como miembro del elemento es no efectiva , porque todos los elementos lo tendrán, independientemente de si realmente aceptan el enfoque o no.
... sino un elemento no va a tomar realmente el foco a menos que sea uno de:
- HTMLAnchorElement/HTMLAreaElement con un href * HTMLInputElement/HTMLSelectElement/HTMLTextAreaElement/HTMLButtonElement pero no con
disabled
(IE realmente le da un error si lo intenta), y las cargas de archivos tienen un comportamiento inusual por razones de seguridad
- HTMLIFrameElement (aunque centrarse no hace nada útil). Otros elementos de inclusión también, tal vez, no los he probado todos.
- Cualquier elemento con un
tabindex
Así que, ¿qué pasa con nombrar a todos aquellos explícitamente en una jQuery Selector?
$('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]')
Actualización # 1:
I updated your jsFiddle here. Parece que funciona
También agregué elementos con el atributo contenteditable
a la lista anterior.
Actualización # 2:
Como @ jfriend00 señaló: "Dependiendo del uso, se puede querer filtrar los elementos que no son visibles". Para lograr esto, simplemente aplique .filter(':visible') al conjunto generado a partir del selector anterior.
Actualización # 3:
Como Xavin pointed out: jQuery UI tiene ahora un selector, :focusable, que realiza esta función. Si ya está utilizando la interfaz de usuario de jQuery, este podría ser el camino a seguir. Si no es así, entonces es posible que desee check out how jQuery UI does it. En cualquier caso, la descripción en la página de jQuery UI para :focusable
es útil:
Elementos del siguiente tipo son enfocable si no se desactivan: de entrada, seleccionar, área de texto, botón, y el objeto. Los anclajes son enfocables si tienen un atributo href o tabindex. los elementos de área son enfocables si están dentro de un mapa con nombre, tienen un atributo href y hay una imagen visible usando el mapa. Todos los otros elementos son enfocables basados únicamente en su atributo tabindex y visibilidad.
Por lo tanto, el selector he propuesto más arriba está cerca, pero no tiene en cuenta algunos matices.
Aquí está la función arrancada de jQuery UI, con pequeñas adaptaciones para que sea autónoma. (Las adaptaciones no se han probado, pero debería funcionar):
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;
}
}
Nota: la función de arriba todavía depende de jQuery, pero no debería requerir jQuery UI.
Probablemente no. Tal vez pruebe el selector [': input'] (http://api.jquery.com/input-selector/)? – Bojangles
¿Qué estás tratando de hacer una vez que tienes la lista de elementos enfocables? – Dennis
@Dennis: desplácese hacia abajo para asegurarse de que estén visibles cuando estén enfocados. http://stackoverflow.com/questions/7650892/how-to-scroll-down-the-page-when-a-covered-input-box-is-focused – ripper234