Cuando ocurre un evento de "desenfoque", ¿cómo puedo saber a qué elemento se centró *a*?

Resuelto Michiel Borkent asked hace 16 años • 23 respuestas

Supongamos que adjunto una blurfunción a un cuadro de entrada HTML como este:

<input id="myInput" onblur="function() { ... }"></input>

¿Hay alguna manera de obtener el ID del elemento que provocó blurque se activara el evento (el elemento en el que se hizo clic) dentro de la función? ¿Cómo?

Por ejemplo, supongamos que tengo un lapso como este:

<span id="mySpan">Hello World</span>

Si hago clic en el intervalo justo después de que el elemento de entrada tenga el foco, el elemento de entrada perderá su foco. ¿Cómo sabe la función en qué se hizo mySpanclic?

PD: Si el evento onclick del intervalo ocurriera antes del evento onblur del elemento de entrada, mi problema se resolvería, porque podría establecer algún valor de estado que indique que se ha hecho clic en un elemento específico.

PPS: El trasfondo de este problema es que quiero activar un control de autocompletado AJAX externamente (desde un elemento en el que se puede hacer clic) para mostrar sus sugerencias, sin que las sugerencias desaparezcan inmediatamente debido al blurevento en el elemento de entrada. Entonces quiero verificar en la blurfunción si se ha hecho clic en un elemento específico y, de ser así, ignorar el evento de desenfoque.

Michiel Borkent avatar Sep 23 '08 21:09 Michiel Borkent
Aceptado

Respuesta de 2015 : según UI Events , puedes usar la relatedTargetpropiedad del evento:

Se utiliza para identificar un secundario EventTargetrelacionado con un evento de Focus, según el tipo de evento.

Para blureventos,

relatedTarget: objetivo del evento que recibe el foco.

Ejemplo:

function blurListener(event) {
  event.target.className = 'blurred';
  if(event.relatedTarget)
    event.relatedTarget.className = 'focused';
}
[].forEach.call(document.querySelectorAll('input'), function(el) {
  el.addEventListener('blur', blurListener, false);
});
.blurred { background: orange }
.focused { background: lime }
<p>Blurred elements will become orange.</p>
<p>Focused elements should become lime.</p>
<input /><input /><input />
Expandir fragmento

Nota Firefox no será compatible relatedTargethasta la versión 48 ( error 962251 , MDN ).

Oriol avatar Oct 25 '2015 03:10 Oriol

Hmm... En Firefox, puedes usar explicitOriginalTargetpara extraer el elemento en el que se hizo clic. Esperaba toElementhacer lo mismo para IE, pero no parece funcionar... Sin embargo, puedes extraer el elemento recién enfocado del documento:

function showBlur(ev)
{
   var target = ev.explicitOriginalTarget||document.activeElement;
   document.getElementById("focused").value = 
      target ? target.id||target.tagName||target : '';
}

...

<button id="btn1" onblur="showBlur(event)">Button 1</button>
<button id="btn2" onblur="showBlur(event)">Button 2</button>
<button id="btn3" onblur="showBlur(event)">Button 3</button>
<input id="focused" type="text" disabled="disabled" />

Advertencia: esta técnica no funciona para los cambios de enfoque causados ​​por la tabulación de campos con el teclado y no funciona en absoluto en Chrome o Safari. El gran problema con el uso activeElement(excepto en IE) es que no se actualiza consistentemente hasta después de queblur se haya procesado el evento, ¡y puede que no tenga ningún valor válido durante el procesamiento! Esto se puede mitigar con una variación de la técnica que Michiel terminó usando :

function showBlur(ev)
{
  // Use timeout to delay examination of activeElement until after blur/focus 
  // events have been processed.
  setTimeout(function()
  {
    var target = document.activeElement;
    document.getElementById("focused").value = 
      target ? target.id||target.tagName||target : '';
  }, 1);
}

Esto debería funcionar en la mayoría de los navegadores modernos (probado en Chrome, IE y Firefox), con la salvedad de que Chrome no se centra en los botones en los que se hace clic (en lugar de en los que se hace clic con pestañas).

Shog9 avatar Sep 23 '2008 15:09 Shog9