event custom javascript events

javascript - custom - Cuando se produce un evento de "desenfoque", ¿cómo puedo averiguar qué elemento de enfoque fue*a*?



mouse events javascript (23)

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

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

¿Hay alguna forma de obtener el ID del elemento que provocó que el evento de blur se disparara (el elemento al 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 tramo 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 que se hizo clic en mySpan ?

PD: Si el evento onclick del lapso 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 hizo clic en un elemento específico.

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


¿Puedes revertir lo que estás comprobando y cuándo? Eso es si recuerdas lo último borroso:

<input id="myInput" onblur="lastBlurred=this;"></input>

y luego en onClick para su span, llame a function () con ambos objetos:

<span id="mySpan" onClick="function(lastBlurred, this);">Hello World</span>

Su función podría entonces decidir si activar o no el control Ajax.AutoCompleter. La función tiene el objeto cliqueado y el objeto borroso. El onBlur ya ha sucedido, por lo que no hará desaparecer las sugerencias.


Como se indica en esta respuesta , puede verificar el valor de document.activeElement . document es una variable global, por lo que no tiene que hacer magia para usarlo en su controlador onBlur:

function myOnBlur(e) { if(document.activeElement === document.getElementById(''elementToCheckForFocus'')) { // Focus went where we expected! // ... } }


Creo que no es posible, con IE puedes intentar usar window.event.toElement , ¡pero no funciona con Firefox!


De esta manera:

<script type="text/javascript"> function yourFunction(element) { alert(element); } </script> <input id="myinput" onblur="yourFunction(this)">

O si adjunta el oyente a través de JavaScript (jQuery en este ejemplo):

var input = $(''#myinput'').blur(function() { alert(this); });

Editar : lo siento. Leí mal la pregunta.


Es posible utilizar el evento mousedown del documento en lugar de desenfoque:

$(document).mousedown(function(){ if ($(event.target).attr("id") == "mySpan") { // some process } });


Escribí una solución alternativa sobre cómo hacer que cualquier elemento sea enfocable y "blurable".

Se basa en hacer un elemento como contenido contentEditable y ocultarlo visualmente y deshabilitar el modo de edición en sí mismo:

el.addEventListener("keydown", function(e) { e.preventDefault(); e.stopPropagation(); }); el.addEventListener("blur", cbBlur); el.contentEditable = true;

MANIFESTACIÓN

Nota: Probado en Chrome, Firefox y Safari (OS X). No estoy seguro acerca de IE.

Relacionado: estaba buscando una solución para VueJs, así que para aquellos interesados ​​/ curiosos en cómo implementar dicha funcionalidad usando la directiva Vue Focusable, por favor echen un vistazo .


Funciona en Google Chrome v66.x, Mozilla v59.x y Microsoft Edge ... Solución con jQuery.

Lo pruebo en Internet Explorer 9 y no es compatible.

$("#YourElement").blur(function(e){ var InputTarget = $(e.relatedTarget).attr("id"); // GET ID Element console.log(InputTarget); if(target == "YourId") { // If you want validate or make a action to specfic element ... // your code } });

Comenta tu prueba en otras versiones de Internet Explorer.


He estado jugando con esta misma característica y descubrí que FF, IE, Chrome y Opera tienen la capacidad de proporcionar el elemento de origen de un evento. No probé Safari, pero creo que podría tener algo similar.

$(''#Form'').keyup(function (e) { var ctrl = null; if (e.originalEvent.explicitOriginalTarget) { // FF ctrl = e.originalEvent.explicitOriginalTarget; } else if (e.originalEvent.srcElement) { // IE, Chrome and Opera ctrl = e.originalEvent.srcElement; } //... });


Hmm ... En Firefox, puedes usar explicitOriginalTarget para tirar del elemento sobre el que se hizo clic. Esperaba que hiciera lo mismo con IE, pero parece que no funciona ... Sin embargo, puede 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 foco causados ​​por tabular los campos con el teclado, y no funciona en absoluto en Chrome o Safari. El gran problema con el uso de activeElement (excepto en IE) es que no se actualiza constantemente hasta que se haya procesado el evento de blur , ¡y puede que no tenga ningún valor válido durante el procesamiento! Esto se puede mitigar con una variación en 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 (probados en Chrome, IE y Firefox), con la advertencia de que Chrome no establece el foco en los botones en los que se hace clic (frente a las pestañas).


Las instancias de FocusEvent han relacionado el atributoTarget, sin embargo, hasta la versión 47 de la FF, específicamente, este atributo devuelve nulo, de 48 que ya funciona.


Lo resolví eventualmente con un tiempo de espera en el evento onblur (gracias al consejo de un amigo que no es ):

<input id="myInput" onblur="setTimeout(function() {alert(clickSrc);},200);"></input> <span onclick="clickSrc=''mySpan'';" id="mySpan">Hello World</span>

Funciona tanto en FF como en IE.


No me gusta utilizar el tiempo de espera cuando codigo javascript, así que lo haría de la manera opuesta a Michiel Borkent. (No probé el código, pero debería entenderse).

<input id="myInput" onblur="blured = this.id;"></input> <span onfocus = "sortOfCallback(this.id)" id="mySpan">Hello World</span>

En la cabeza algo así

<head> <script type="text/javascript"> function sortOfCallback(id){ bluredElement = document.getElementById(blured); // Do whatever you want on the blured element with the id of the focus element } </script> </head>


Podrías hacerlo así:

<script type="text/javascript"> function myFunction(thisElement) { document.getElementByName(thisElement)[0]; } </script> <input type="text" name="txtInput1" onBlur="myFunction(this.name)"/>


Puedes arreglar IE con:

event.currentTarget.firstChild.ownerDocument.activeElement

Se ve como "explicitOriginalTarget" para FF.

Antoine y J



Sugiero usar variables globales blurfrom y blurto. Luego, configure todos los elementos que le interesan para asignar su posición en el DOM a la variable borrosa de cuando pierden el foco. Además, configúrelos de modo que obtener el foco establezca la variable blurto en su posición en el DOM. Entonces, podría usar otra función completamente para analizar el desenfoque y los datos blurto.


También estoy tratando de hacer que Autocompleter ignore la borrosidad si se hace clic en un elemento específico y tiene una solución funcional, pero solo para Firefox debido a explicitOriginalTarget

Autocompleter.Base.prototype.onBlur = Autocompleter.Base.prototype.onBlur.wrap( function(origfunc, ev) { if ($(this.options.ignoreBlurEventElement)) { var newTargetElement = (ev.explicitOriginalTarget.nodeType == 3 ? ev.explicitOriginalTarget.parentNode : ev.explicitOriginalTarget); if (!newTargetElement.descendantOf($(this.options.ignoreBlurEventElement))) { return origfunc(ev); } } } );

Este código ajusta por defecto el método Blur de Autocompletar y comprueba si se establece el parámetro ignoreBlurEventElement. si está configurado, comprueba cada vez para ver si el elemento cliqueado es ignoreBlurEventElement o no. Si es así, Autocompleter no llama a Blur, de lo contrario llama a Blur. El único problema con esto es que solo funciona en Firefox porque la propiedad explicitOriginalTarget es específica de Mozilla. Ahora estoy tratando de encontrar una forma diferente de usar explicitOriginalTarget. La solución que ha mencionado requiere que agregue el comportamiento onclick manualmente al elemento. Si no puedo resolver el problema de explicitoOriginalTarget, supongo que seguiré tu solución.


Usa algo como esto:

var myVar = null;

Y luego dentro de tu función:

myVar = fldID;

Y entonces:

setTimeout(setFocus,1000)

Y entonces:

function setFocus(){ document.getElementById(fldID).focus(); }

Código final:

<html> <head> <script type="text/javascript"> function somefunction(){ var myVar = null; myVar = document.getElementById(''myInput''); if(myVar.value=='''') setTimeout(setFocusOnJobTitle,1000); else myVar.value=''Success''; } function setFocusOnJobTitle(){ document.getElementById(''myInput'').focus(); } </script> </head> <body> <label id="jobTitleId" for="myInput">Job Title</label> <input id="myInput" onblur="somefunction();"></input> </body> </html>


tenga en cuenta que la solución con explicitOriginalTarget no funciona para saltos de entrada de texto a entrada de texto.

intente reemplazar los botones con las siguientes entradas de texto y verá la diferencia:

<input id="btn1" onblur="showBlur(event)" value="text1"> <input id="btn2" onblur="showBlur(event)" value="text2"> <input id="btn3" onblur="showBlur(event)" value="text3">


Editar: Una forma estrafalaria de hacerlo sería crear una variable que haga un seguimiento del enfoque para cada elemento que te interese. Por lo tanto, si le importa que ''myInput'' pierda el foco, establezca una variable en el foco.

<script type="text/javascript"> var lastFocusedElement; </script> <input id="myInput" onFocus="lastFocusedElement=this;" />

Respuesta original: puede pasar ''esto'' a la función.

<input id="myInput" onblur="function(this){ var theId = this.id; // will be ''myInput'' }" />


Respuesta de 2015 : según los eventos de UI , puede usar la propiedad de relatedTarget del evento:

Se usa para identificar una EventTarget secundaria relacionada con un evento Focus, según el tipo de evento.

Para eventos blur ,

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 />

Tenga en cuenta que Firefox no admitirá relatedTarget hasta la versión 48 ( error 962251 , MDN ).



Creo que es muy posible a través de jquery al pasar la referencia del campo que causa el evento onblur en "esto".
Por ej.

<input type="text" id="text1" onblur="showMessageOnOnblur(this)"> function showMessageOnOnblur(field){ alert($(field).attr("id")); }

Gracias
Monika


  • document.activeElement podría ser un nodo principal (por ejemplo, un nodo del cuerpo porque está en una fase temporal que cambia de un destino a otro), por lo que no es utilizable para su alcance
  • ev.explicitOriginalTarget no siempre se valora

Entonces, la mejor manera es usar onclick en el evento del cuerpo para entender indirectamente que su nodo (event.target) está en blur