¿Cómo puedo saber qué elemento DOM tiene foco?

Me gustaría saber, en Javascript, qué elemento está enfocado 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?

Estaba buscando esto:

Estoy tratando de hacer teclas como flechas, y enter navegar a través de la tabla de elementos de entrada. Ahora la pestaña funciona, pero la entrada y las flechas por defecto no se muestran. Tengo parte del manejo de claves, pero ahora necesito averiguar cómo mover el enfoque en la función de manejo de eventos.

931
30 янв. Tony Peterson ambientó el 30 de enero 2009-01-30 23:21 '09 a las 11:21 PM 2009-01-30 23:21
@ 18 respuestas

Use document.activeElement , es compatible con todos los principales navegadores.

Anteriormente, si intentaba averiguar qué campo del formulario está concentrado, 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 campo con el último foco en una variable. Agregue un controlador de "desenfoque" para borrar la variable en el evento de desenfoque para el campo con el último foco.

Enlaces relacionados:

1083
La respuesta es dada por JW. 30 de enero 2009-01-30 23:24 '09 a las 23:24 2009-01-30 23:24

Como dijo JW, no puedes encontrar el elemento enfocado actual, al menos independientemente del navegador. Pero si su aplicación es solo IE (algunas de ellas ...), puede encontrarla de la siguiente manera:

 document.activeElement 
border=0

EDITAR: Parece que IE no tenía nada malo, es parte de un borrador de HTML5, y parece ser compatible con la última versión de Chrome, Safari y Firefox al menos.

100
30 янв. La respuesta se da Wookai 30 de enero. 2009-01-30 23:34 '09 a las 23:34 2009-01-30 23:34

Si puede usar jQuery, ahora es compatible con: focus, solo asegúrese de estar usando la versión 1.6+.

Este operador le proporcionará el elemento enfocado actualmente.

 $(":focus") 

De: Cómo seleccionar un elemento que se enfoca en él usando jQuery

73
27 авг. Respuesta dada por William Denniss el 27 de agosto. 2011-08-27 20:33 '11 a las 20:33 2011-08-27 20:33

document.activeElement ahora document.activeElement parte de la especificación HTML5 del borrador de trabajo , pero es posible que aún no sea compatible con algunos navegadores que no admiten Basic / Mobile / old. Puede volver a querySelector (si es compatible). También vale la pena señalar 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 volverá 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"); 

Además, debe tenerse en cuenta la diferencia de rendimiento entre los dos métodos. Solicitar un documento con selectores siempre será mucho más lento que acceder a la propiedad activeElement . Ver esta prueba jsperf.com .

36
19 окт. la respuesta es dada por Andy E 19 oct. 2011-10-19 16:01 '11 a las 16:01 2011-10-19 16:01

document.activeElement puede usar el elemento <body> de forma predeterminada si no hay elementos enfocados enfocados. Además, si el elemento está enfocado y la ventana del navegador está borrosa, activeElement continuará manteniendo el elemento enfocado.

Si uno de estos dos comportamientos es indeseable, considere un enfoque basado en CSS: document.querySelector( ':focus' ) .

11
06 авг. respuesta dada por Nate Whittaker 06 de agosto 2014-08-06 22:32 '14 a las 10:32 pm 2014-08-06 22:32

Me gustó el enfoque adoptado por Joel S., pero también me gusta 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); 
10
08 сент. Responder a Jason Sep 08 2010-09-08 21:47 '10 a las 21:47 2010-09-08 21:47

Un pequeño asistente que utilicé para este propósito 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 startFocusTracking() llamado a startFocusTracking() para este elemento.

9
04 февр. La respuesta la da Joel S 04 feb. 2010-02-04 15:36 '10 a las 15:36 2010-02-04 15:36

JQuery admite la pseudo-clase :focus comparación con la actual. Si lo está buscando en la documentación de jQuery, consulte la sección "Selectores" donde apunta a los documentos CSS del W3C . He probado Chrome, FF y IE 7+. Tenga en cuenta que para trabajar en IE en la página html debe existir <!DOCTYPE... Aquí hay un ejemplo que asume que asignó un identificador a un elemento con un enfoque:

 $(":focus").each(function() { alert($(this).attr("id") + " has focus!"); }); 
7
11 марта '11 в 2:10 2011-03-11 02:10 DeezCashews da la respuesta el 11 de marzo de 2011 a las 2:10 2011-03-11 02:10

Hay problemas potenciales con el uso de document.activeElement. Considere:

 <div contentEditable="true"> <div>Some text</div> <div>Some text</div> <div>Some text</div> </div> 

Si el usuario se enfoca en div interno, entonces document.activeElement todavía se refiere a la div externa. No puede usar document.activeElement para determinar cuál de los divs internos tiene el foco.

La siguiente función recorre esto y devuelve el nodo enfocado:

 function active_node(){ return window.getSelection().anchorNode; } 

Si prefiere obtener un artículo enfocado, use:

 function active_element(){ var anchor = window.getSelection().anchorNode; if(anchor.nodeType == 3){ return anchor.parentNode; }else if(anchor.nodeType == 1){ return anchor; } } 
5
01 марта '15 в 10:36 2015-03-01 10:36 La respuesta es dada por Nathan K el 1 de marzo de 2015 a las 10:36 2015-03-01 10:36

Después de leer las otras respuestas e intentarlo usted mismo, parece que document.activeElement le proporcionará el elemento que necesita en la mayoría de los navegadores.

Si tiene un navegador que no admite document.activeElement, si tiene jQuery, puede completar todos los eventos de enfoque con algo muy simple (sin probar, ya que no tengo un navegador, los criterios de entrega):

 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 }); } 
5
05 авг. la respuesta se da rjmunro 05 ago. 2011-08-05 02:20 '11 a las 2:20 2011-08-05 02:20

Si desea obtener un objeto que sea una instancia de un Element , debe usar document.activeElement , pero si desea obtener un objeto que es una instancia de Text , debe usar document.getSelection().focusNode .

Espero que esto ayude.

5
17 июля '16 в 8:52 2016-07-17 08:52 la respuesta se da rplaurindo 17 de julio de 2016 a las 8:52 2016-07-17 08:52

Si está utilizando jQuery, puede usar esto para averiguar si el elemento está activo:

 $("input#id").is(":active"); 
5
14 февр. La respuesta la da Arne el 14 de febrero. 2012-02-14 22:29 '12 a las 10:29 pm 2012-02-14 22:29

document.activeElement propio document.activeElement puede devolver un elemento si el documento no está enfocado. Es posible que desee este comportamiento, pero si no lo hace, puede verificar document.hasFocus() :

 var focused_element = document.hasFocus()  document.activeElement !== document.body  document.activeElement !== document.documentElement  document.activeElement; 

Para verificar si un elemento en particular tiene un foco:

 var input_focused = document.activeElement === input  document.hasFocus(); 

Alternativamente, puede usar eventos, pero esto requiere instalación y asume el estado inicial:

 var input_focused = false; input.addEventListener("focus", function() { input_focused = true; }); input.addEventListener("blur", function() { input_focused = false; }); 
5
29 нояб. La respuesta se da 1j01 29 nov. 2016-11-29 21:51 '16 a las 21:51 2016-11-29 21:51

Con dojo, puedes usar dijit.getFocus ()

4
13 янв. Respuesta dada por Daniel Hartmann el 13 de enero. 2012-01-13 14:55 '12 a las 2:55 pm 2012-01-13 14:55

Solo lo puse aquí para dar una solución, que finalmente se me ocurrió.

Creé la propiedad document.activeInputArea y usé el complemento jQuery HotKeys para bloquear eventos de teclado para las teclas de flecha, las pestañas y la entrada, y creé un controlador de eventos para hacer clic en los elementos de entrada.

Luego cambié activeInputArea cada vez que cambiaba el enfoque, de modo que pudiera usar esta propiedad para averiguar dónde estaba.

Es fácil estropearlo, porque si tienes un error en el sistema y el enfoque no está donde crees que está, entonces es muy difícil restablecer el enfoque correcto.

3
18 мая '09 в 15:48 2009-05-18 15:48 contestado por Tony Peterson el 18 de mayo de 2009 a las 15:48 2009-05-18 15:48

Quirksmode hizo una forma casi independiente de lograrlo desde hace mucho tiempo. Puede tener problemas con Safari, ya que Safari no siempre configura eventos en los mismos elementos que Chrome o Firefox. A veces, Safari incluso establece un evento en un campo de texto en lugar del elemento que lo contiene. Esto se puede arreglar después de un tiempo (verificando el tipo de nodo).

Aquí está:

  function getFocus(e){ var focused; if (!e) var e = window.event; if (e.target) focused = e.target; else if (e.srcElement) focused = e.srcElement; if (focused.nodeType == 3) focused = focused.parentNode; if (document.querySelector) { return focused.id; } else if (!focused || focused == document.documentElement) { return focused; } } 

Espero que esto ayude.


Gracias Quirksmode

2
04 июля '17 в 16:57 2017-07-04 16:57 La respuesta la da fred heuvel el 4 de julio de 2017 a las 16:57 2017-07-04 16:57

Google Chrome (al menos hasta 33) tiene un error molesto con document.activeElement : XHTML document.activeElement undefined . No he probado otros navegadores basados ​​en webkit, también pueden verse afectados.

1
05 дек. Respuesta dada por Duan Yao 05 dic. 2017-12-05 01:03 '17 a la 1:03 2017-12-05 01:03

Encontré el siguiente fragmento de código, que será útil cuando se trate de determinar qué elemento tiene el foco actualmente. Copie lo siguiente en la consola de su navegador, y cada segundo imprime los detalles del elemento actual con foco.

 setInterval(function() { console.log(document.querySelector(":focus")); }, 1000); 

Siéntase libre de modificar console.log para mostrar otra cosa que le ayude a identificar el elemento exacto si una lista de todo el elemento no le ayuda a identificar el elemento.

0
20 окт. La respuesta se da vegemite4me 20 oct. 2017-10-20 14:20 '17 a las 2:20 pm 2017-10-20 14:20

Otras preguntas sobre las etiquetas o hacer una pregunta