Cuando ocurre un evento de "desenfoque", ¿cómo puedo saber a qué elemento se centró *a*?
Supongamos que adjunto una blur
funció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ó blur
que 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 mySpan
clic?
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 blur
evento en el elemento de entrada. Entonces quiero verificar en la blur
función si se ha hecho clic en un elemento específico y, de ser así, ignorar el evento de desenfoque.
Respuesta de 2015 : según UI Events , puedes usar la relatedTarget
propiedad del evento:
Se utiliza para identificar un secundario
EventTarget
relacionado con un evento de Focus, según el tipo de evento.
Para blur
eventos,
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 />
Nota Firefox no será compatible relatedTarget
hasta la versión 48 ( error 962251 , MDN ).
Hmm... En Firefox, puedes usar explicitOriginalTarget
para extraer el elemento en el que se hizo clic. Esperaba toElement
hacer 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).