javascript - etiqueta - select html ejemplos
¿Cómo puedo saber qué elemento DOM tiene el enfoque? (16)
Me gustaría descubrir, en JavaScript, qué elemento tiene el foco actualmente. He estado buscando en el DOM y aún no he encontrado lo que necesito. ¿Hay una 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 ingrese, y las flechas no lo hacen por defecto. Tengo configurada la parte de manejo de claves, pero ahora tengo que averiguar cómo mover el enfoque en las funciones de manejo de eventos.
Al leer otras respuestas y probarlo, parece que document.activeElement
le dará el elemento que necesita en la mayoría de los navegadores.
Si tiene un navegador que no es compatible con document.activeElement si tiene jQuery, debería poder poblarlo en todos los eventos de enfoque con algo muy simple como este (sin probar, ya que no tengo un navegador que cumpla con esos criterios) ):
if (typeof document.activeElement === ''undefined'') { // Check browser doesn''t do it anyway
$(''*'').live(''focus'', function () { // Attach to all focus events using .live()
document.activeElement = this; // Set activeElement to the element that has been focussed
});
}
Como dijo JW, no puede encontrar el elemento enfocado actual, al menos de forma independiente del navegador. Pero si su aplicación es solo para IE (algunos son ...), puede encontrarla de la siguiente manera:
document.activeElement
EDITAR: Parece que IE no tenía todo mal después de todo, esto es parte del borrador de HTML5 y parece ser compatible con la última versión de Chrome, Safari y Firefox al menos.
Con dojo, puedes usar dijit.getFocus ()
Hay problemas potenciales con el uso de document.activeElement. Considerar:
<div contentEditable="true">
<div>Some text</div>
<div>Some text</div>
<div>Some text</div>
</div>
Si el usuario se enfoca en una división interna, entonces document.activeElement todavía hace referencia a la división externa. No puede usar document.activeElement para determinar cuál de los div internos tiene enfoque.
La siguiente función soluciona esto y devuelve el nodo enfocado:
function active_node(){
return window.getSelection().anchorNode;
}
Si prefiere obtener el elemento enfocado, use:
function active_element(){
var anchor = window.getSelection().anchorNode;
if(anchor.nodeType == 3){
return anchor.parentNode;
}else if(anchor.nodeType == 1){
return anchor;
}
}
He encontrado que el siguiente fragmento de código es útil al tratar de determinar qué elemento tiene el foco actualmente. Copie lo siguiente en la consola de su navegador, y cada segundo imprimirá los detalles del elemento actual que tiene el foco.
setInterval(function() { console.log(document.querySelector(":focus")); }, 1000);
Siéntase libre de modificar el console.log
para cerrar sesión en algo diferente que lo ayude a identificar el elemento exacto si la impresión de todo el elemento no lo ayuda a identificar el elemento.
JQuery admite la pseudo-clase :focus
desde la fecha actual. Si lo busca en la documentación de JQuery, verifique en "Selectores" donde le indica la documentación 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. Este es un ejemplo que asume que ha asignado una identificación al elemento que tiene el foco:
$(":focus").each(function() {
alert($(this).attr("id") + " has focus!");
});
Me gustó el enfoque utilizado por Joel S, pero también me encanta la simplicidad de document.activeElement
. Utilicé jQuery y combiné los dos. Los navegadores más antiguos que no admiten document.activeElement
usarán jQuery.data()
para almacenar el valor de ''hasFocus''. Los navegadores más nuevos usarán document.activeElement
. Supongo que document.activeElement
tendrá un mejor rendimiento.
(function($) {
var settings;
$.fn.focusTracker = function(options) {
settings = $.extend({}, $.focusTracker.defaults, options);
if (!document.activeElement) {
this.each(function() {
var $this = $(this).data(''hasFocus'', false);
$this.focus(function(event) {
$this.data(''hasFocus'', true);
});
$this.blur(function(event) {
$this.data(''hasFocus'', false);
});
});
}
return this;
};
$.fn.hasFocus = function() {
if (this.length === 0) { return false; }
if (document.activeElement) {
return this.get(0) === document.activeElement;
}
return this.data(''hasFocus'');
};
$.focusTracker = {
defaults: {
context: ''body''
},
focusedElement: function(context) {
var focused;
if (!context) { context = settings.context; }
if (document.activeElement) {
if ($(document.activeElement).closest(context).length > 0) {
focused = document.activeElement;
}
} else {
$('':visible:enabled'', context).each(function() {
if ($(this).data(''hasFocus'')) {
focused = this;
return false;
}
});
}
return $(focused);
}
};
})(jQuery);
Por sí mismo, document.activeElement
todavía puede devolver un elemento si el documento no está enfocado (y por lo tanto, ¡ nada en el documento está enfocado!)
Puede querer ese comportamiento, o puede que no importe (por ejemplo, dentro de un evento de keydown
), pero si necesita saber que algo está realmente enfocado, también puede verificar document.hasFocus()
.
Lo siguiente le dará el elemento enfocado si hay uno, o bien null
.
var focused_element = null;
if (
document.hasFocus() &&
document.activeElement !== document.body &&
document.activeElement !== document.documentElement
) {
focused_element = document.activeElement;
}
Para verificar si un elemento específico tiene foco, es más simple:
var input_focused = document.activeElement === input && document.hasFocus();
Para comprobar si algo está enfocado, es más complejo de nuevo:
var anything_is_focused = (
document.hasFocus() &&
document.activeElement !== null &&
document.activeElement !== document.body &&
document.activeElement !== document.documentElement
);
Robustez Nota : en el código donde se verifica el document.body
y document.documentElement
, esto se debe a que algunos navegadores devuelven uno de estos o null
cuando no hay nada centrado.
No tiene en cuenta si <body>
(o tal vez <html>
) tenía un atributo tabIndex
y, por lo tanto, podría estar enfocado . Si estás escribiendo una biblioteca o algo y quieres que sea robusto, probablemente deberías manejar eso de alguna manera.
Aquí hay una versión (de una sola línea) de "one-liner" de obtener el elemento enfocado, que es conceptualmente más complicado porque tiene que saber acerca de los cortocircuitos, y ya sabe, obviamente no cabe en una línea, asumiendo que quiero que sea legible.
No voy a recomendar este. Pero si eres un 1337 hax0r, idk ... está ahí.
También podría eliminar el || null
Parte || null
si no te importa false
en algunos casos. (Aún podría obtener null
si document.activeElement
es null
):
var focused_element = (
document.hasFocus() &&
document.activeElement !== document.body &&
document.activeElement !== document.documentElement &&
document.activeElement
) || null;
Para verificar si un elemento específico está enfocado, alternativamente, podría usar eventos, pero de esta manera se requiere configuración (y potencialmente demolición) y, lo que es más importante, asume un estado inicial :
var input_focused = false;
input.addEventListener("focus", function() {
input_focused = true;
});
input.addEventListener("blur", function() {
input_focused = false;
});
Podría arreglar la suposición del estado inicial utilizando la forma sin eventos, pero también podría usar eso en su lugar.
Si desea obtener un objeto que es una instancia de Element
, debe usar document.activeElement
, pero si desea obtener un objeto que es una instancia de Text
, debe usar document.getSelection().focusNode
.
Espero que ayude.
Si está utilizando jQuery, puede usar esto para averiguar si un elemento está activo:
$("input#id").is(":active");
Si puede usar jQuery, ahora es compatible con: focus, solo asegúrese de estar usando la versión 1.6+.
Esta declaración te dará el elemento enfocado actualmente.
$(":focus")
Solo pongo esto aquí para dar la solución que se me ocurrió.
Creé una propiedad llamada document.activeInputArea y utilicé el complemento HotKeys de jQuery para capturar 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 enfoque, para poder usar esa propiedad para averiguar dónde estaba.
Sin embargo, es fácil arruinar esto, porque si tienes un error en el sistema y el enfoque no es donde crees que está, entonces es muy difícil restaurar el enfoque correcto.
Un pequeño ayudante que he usado para estos propósitos en Mootools:
FocusTracker = {
startFocusTracking: function() {
this.store(''hasFocus'', false);
this.addEvent(''focus'', function() { this.store(''hasFocus'', true); });
this.addEvent(''blur'', function() { this.store(''hasFocus'', false); });
},
hasFocus: function() {
return this.retrieve(''hasFocus'');
}
}
Element.implement(FocusTracker);
De esta manera puede verificar si el elemento tiene enfoque con el.hasFocus()
siempre que se haya llamado a startFocusTracking()
en el elemento dado.
Use document.activeElement
, es compatible con todos los principales navegadores.
Anteriormente, si intentaba averiguar qué campo de formulario tiene el foco, no podría. Para emular la detección en navegadores más antiguos, agregue un controlador de eventos de "enfoque" a todos los campos y registre el último campo enfocado en una variable. Agregue un controlador de "desenfoque" para borrar la variable en un evento de desenfoque para el último campo enfocado.
Enlaces relacionados:
document.activeElement
ahora es parte de la especificación de borrador de trabajo de HTML5 , pero puede que aún no sea compatible con algunos navegadores no principales / móviles / antiguos. Puede recurrir a querySelector
(si se admite). También vale la pena mencionar que document.activeElement
devolverá document.body
si no hay ningún elemento enfocado, incluso si la ventana del navegador no tiene el foco.
El siguiente código evitará este problema y recurrirá a querySelector
brindando un poco mejor soporte.
var focused = document.activeElement;
if (!focused || focused == document.body)
focused = null;
else if (document.querySelector)
focused = document.querySelector(":focus");
Una cosa 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 propiedad activeElement
. Vea esta prueba de jsperf.com .
document.activeElement
puede predeterminar el elemento <body>
si no hay elementos enfocados en el foco. 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 es deseable, considere un enfoque basado en CSS: document.querySelector( '':focus'' )
.