Me gustaría descubrir, en JavaScript, qué elemento tiene el foco actualmente. He estado buscando en el DOM y todavía no he encontrado lo que necesito. ¿Hay alguna manera de hacer esto y cómo?
La razón por la que estaba buscando esto:
Estoy tratando de hacer teclas como las flechas y enter
navegar a través de una tabla de elementos de entrada. La pestaña funciona ahora, pero ingresa, y las flechas no lo hacen de manera predeterminada. Tengo configurada la parte de manejo de claves, pero ahora necesito descubrir cómo mover el foco en las funciones de manejo de eventos.
javascript
dom
Tony Peterson
fuente
fuente
find-focused-element
paquete: npmjs.com/package/find-focused-elementRespuestas:
Uso
document.activeElement
, es compatible con todos los principales navegadores.Anteriormente, si intentaba averiguar qué campo de formulario tenía el foco, no podía. Para emular la detección en navegadores antiguos, agregue un controlador de eventos "focus" a todos los campos y registre el último campo enfocado en una variable. Agregue un controlador "desenfoque" para borrar la variable en un evento de desenfoque para el último campo enfocado.
Si necesita eliminar el
activeElement
puede usar desenfoque;document.activeElement.blur()
. Cambiará elactiveElement
abody
.Enlaces relacionados:
fuente
activeElement
en realidad no devuelve el elemento enfocado. Cualquier elemento puede tener foco. Si un documento tiene 4 'scrolldivs', 0 o 1 de esos divs se puede desplazar con las teclas de flecha. Si hace clic en uno, ese div se enfoca. Si hace clic fuera de todo, el cuerpo está enfocado. ¿Cómo saber qué scrolldiv está enfocado? jsfiddle.net/rudiedirkx/bC5ke/show (ver consola)div
es Firefox 17, y solo presionándolo . Los tipos de elementos a través de los cuales TODOS los principales navegadores regresandocument.activeElement
están restringidos a elementos relacionados con la entrada . Si ningún elemento de este tipo tiene el foco, todos los navegadores principales devuelven elbody
elemento, excepto IE 9, que devuelve elhtml
elemento.document.activeElement
debe estar envuelto en un,try catch
ya que en algunas circunstancias puede arrojar una excepción (no solo IE9 AFAIK). Ver bugs.jquery.com/ticket/13393 y bugs.jqueryui.com/ticket/8443Como dijo JW, no puede encontrar el elemento enfocado actual, al menos de forma independiente del navegador. Pero si su aplicación es solo IE (algunas son ...), puede encontrarla de la siguiente manera:
EDITAR: Parece que IE no tenía todo mal después de todo, esto es parte del borrador HTML5 y parece ser compatible con la última versión de Chrome, Safari y Firefox al menos.
fuente
Si puede usar jQuery, ahora es compatible con: focus, solo asegúrese de estar utilizando la versión 1.6+.
Esta declaración le dará el elemento actualmente enfocado.
De: Cómo seleccionar un elemento que se centra en él con jQuery
fuente
return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
document.activeElement
ahora es parte de la especificación del borrador de trabajo HTML5 , pero es posible que aún no sea compatible con algunos navegadores no principales / móviles / antiguos. Puede recurrir aquerySelector
(si eso es compatible). También vale la pena mencionar quedocument.activeElement
volverádocument.body
si ningún elemento está enfocado, incluso si la ventana del navegador no tiene el foco.El siguiente código solucionará este problema y recurrirá a
querySelector
brindar un poco mejor soporte.Una cosa adicional a tener en cuenta es la diferencia de rendimiento entre estos dos métodos. Consultar el documento con selectores siempre será mucho más lento que acceder a la
activeElement
propiedad. Vea esta prueba de jsperf.com .fuente
Por sí solo,
document.activeElement
aún puede devolver un elemento si el documento no está enfocado (¡y por lo tanto, nada en el documento está enfocado!)Es posible que desee ese comportamiento, o puede que no importe (por ejemplo, dentro de un
keydown
evento), pero si necesita saber que algo está realmente enfocado, también puede verificarlodocument.hasFocus()
.Lo siguiente le dará el elemento enfocado si hay uno, o si no
null
.Para verificar si un elemento específico tiene foco, es más simple:
Para verificar si algo está enfocado, es más complejo nuevamente:
Nota de robustez : en el código donde se compara
document.body
ydocument.documentElement
, esto se debe a que algunos navegadores devuelven uno de estos onull
cuando nada está enfocado.No tiene en cuenta si el
<body>
(o tal vez<html>
) tenía untabIndex
atributo y, por lo tanto, podría enfocarse . Si está escribiendo una biblioteca o algo y quiere que sea robusta, probablemente debería manejar eso de alguna manera.Aquí hay una versión de "un trazo" ( comillas aéreas pesadas ) para obtener el elemento enfocado, que es conceptualmente más complicado porque tienes que saber sobre el cortocircuito y, obviamente, no cabe en una línea, suponiendo que quiero que sea legible.
No voy a recomendar este. Pero si eres un 1337 hax0r, idk ... está ahí.
También puede eliminar la
|| null
pieza si no le importafalse
en algunos casos. (Aún podría obtenernull
sidocument.activeElement
esnull
):Para verificar si un elemento específico está enfocado, alternativamente podría usar eventos, pero de esta manera requiere configuración (y potencialmente desmontaje), y lo que es más importante, asume un estado inicial :
Puede corregir la suposición de estado inicial utilizando la forma no especificada, pero también podría usarla en su lugar.
fuente
document.activeElement
puede ser el<body>
elemento predeterminado si no hay elementos enfocables enfocados. Además, si un elemento está enfocado y la ventana del navegador está borrosa,activeElement
continuará manteniendo el elemento enfocado.Si cualquiera de estos dos comportamientos no son deseables, considerar un enfoque basado en CSS:
document.querySelector( ':focus' )
.fuente
querySelector
: stackoverflow.com/a/40873560/2624876Me gustó el enfoque utilizado por Joel S, pero también me encanta la simplicidad de
document.activeElement
. Usé jQuery y combiné los dos. Los navegadores más antiguos que no son compatiblesdocument.activeElement
lo usaránjQuery.data()
para almacenar el valor de 'hasFocus'. Se utilizarán navegadores más nuevosdocument.activeElement
. Supongo quedocument.activeElement
tendrá un mejor rendimiento.fuente
$("*:focus")
?Un pequeño ayudante que he usado para estos propósitos en Mootools:
De esta manera, puede verificar si el elemento tiene el foco
el.hasFocus()
siempre questartFocusTracking()
se haya llamado al elemento dado.fuente
JQuery admite la
:focus
pseudoclase a partir de la corriente. Si lo está buscando en la documentación de JQuery, consulte "Selectores" donde le señala los documentos CSS del W3C . He probado con Chrome, FF e IE 7+. Tenga en cuenta que para que funcione en IE,<!DOCTYPE...
debe existir en la página html. Aquí hay un ejemplo asumiendo que ha asignado una identificación al elemento que tiene foco:fuente
this.id
lugar de$(this).attr('id')
, o al menos (cuando ya tiene su objeto jQuery)$(this)[0].id
. Javascript nativo en este nivel es MUCHO más rápido y más eficiente. Puede no ser notable en este caso, pero en todo el sistema notará una diferencia.Si desea obtener un objeto de instancia
Element
, debe usarlodocument.activeElement
, pero si desea obtener un objeto de instanciaText
, debe usarlodocument.getSelection().focusNode
.Espero ayuda
fuente
document.getSelection().focusNode.parentElement
y toque Entrar. Después de eso, pasadocument.activeElement
y haz lo mismo. ;)document.activeElement
da el<textarea>
whiledocument.getSelection().focusNode
da el<td>
que contiene el<textarea>
(ydocument.getSelection().focusNode.parentElement
da el que<tr>
contiene el<td>
)Element
, debe usarlodocument.activeElement
, pero si desea obtener un objeto de instanciaText
, debe usarlodocument.getSelection().focusNode
. Por favor, pruébalo de nuevo. Espero haberte ayudado.focusNode
tampoco se garantiza que sea un nodo de texto.Hay posibles problemas con el uso de document.activeElement. Considerar:
Si el usuario se centra en un div interno, document.activeElement todavía hace referencia al div externo. No puede usar document.activeElement para determinar cuál de los div internos tiene foco.
La siguiente función evita esto y devuelve el nodo enfocado:
Si prefiere obtener el elemento enfocado, use:
fuente
document.activeElement
: los<div>
elementos internos en realidad no pueden recibir el foco, como puede ver visualmente configurando la:focus
pseudo-clase en algo visible (ejemplo: jsfiddle.net/4gasa1t2/1 ). De lo que estás hablando es de cuál de los<div>
s internos contiene la selección o el cursor, que es un tema separado.He encontrado que el siguiente fragmento es útil cuando intento determinar qué elemento tiene foco actualmente. Copie lo siguiente en la consola de su navegador, y cada segundo imprimirá los detalles del elemento actual que tiene el foco.
Siéntase libre de modificar
console.log
para cerrar sesión algo diferente para ayudarlo a identificar el elemento exacto si imprimir todo el elemento no lo ayuda a identificar el elemento.fuente
Al leer otras respuestas e intentarlo, parece que
document.activeElement
le dará el elemento que necesita en la mayoría de los navegadores.Si tiene un navegador que no admite document.activeElement si tiene jQuery, debería poder completarlo en todos los eventos de enfoque con algo muy simple como esto (no probado, ya que no tengo un navegador que cumpla con esos criterios a mano) ):
fuente
Si está usando jQuery, puede usar esto para averiguar si un elemento está activo:
fuente
Con dojo, puede usar dijit.getFocus ()
fuente
Solo pongo esto aquí para dar la solución que finalmente se me ocurrió.
Creé una propiedad llamada document.activeInputArea, y usé el complemento HotQeys de jQuery para atrapar eventos de teclado para las teclas de flecha, tabular e ingresar, y creé un controlador de eventos para hacer clic en los elementos de entrada.
Luego ajusté activeInputArea cada vez que cambiaba el foco, para poder usar esa propiedad para averiguar dónde estaba.
Sin embargo, es fácil arruinar esto, porque si tiene un error en el sistema y el foco no está donde cree que está, entonces es muy difícil restaurar el foco correcto.
fuente