Cuando un "desenfoque" se produce un evento, ¿cómo puedo saber cuál es el foco del elemento se fue *a*?

StackOverflow https://stackoverflow.com/questions/121499

  •  02-07-2019
  •  | 
  •  

Pregunta

Supongamos que adjuntar una blur la función de HTML de una entrada de caja como esta:

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

Hay una manera de obtener el ID del elemento que causó la blur evento para el fuego (el elemento que se ha hecho clic) dentro de la función?Cómo?

Por ejemplo, supongamos que tengo un palmo, como este:

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

Si hago clic en el lapso de la derecha después de que el elemento tiene el foco de entrada, el elemento de entrada va a perder su enfoque.¿Cómo funciona la función de saber que era mySpan que hizo?

PS:Si el evento onclick del tramo ocurrir antes de que el evento onblur del elemento de entrada mi problema estaría resuelto, porque yo podría establecer algún valor de estado que indica un elemento específico había sido pulsado.

PPS:El fondo de este problema es que quiero activar un AJAX autocompleter de control externo (de un clickable elemento) para mostrar sus sugerencias, sin las sugerencias de desaparecer de inmediato, porque de la blur evento en el elemento de entrada.Así que quiero ver en el blur función de si un elemento específico que se ha hecho clic, y si es así, ignorar el efecto de desenfoque del evento.

¿Fue útil?

Solución

Hmm...En Firefox, puede utilizar explicitOriginalTarget para tirar el elemento que se ha hecho clic en.Yo esperaba toElement hacer lo mismo para el IE, pero no parece funcionar...Sin embargo, usted puede tirar de la recién centrado elemento 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 hace no trabajo para el enfoque de los cambios causados por tabulación a través de los campos con el teclado, y no funciona en Chrome o Safari.El gran problema con el uso de activeElement (excepto en IE) es que no se actualiza constantemente hasta que después de el blur evento ha sido procesado, y pueden no tener ningún valor válido en absoluto durante el proceso!Esto puede ser mitigado con una variación de la técnica de Michiel terminó con:

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 establecer el foco en los botones que se clic (vstabular).

Otros consejos

2015 responder:de acuerdo a Eventos de interfaz de usuario, usted puede utilizar el relatedTarget propiedad de el evento:

Se utiliza para identificar a una secundaria EventTarget relativa a un Enfoque evento, dependiendo del tipo de evento.

Para blur eventos,

relatedTarget: destino del evento recibir 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 soporta relatedTarget hasta la versión 48 (error 962251, MDN).

He resuelto finalmente con un tiempo de espera en el evento onblur (gracias a los consejos de un amigo que no es de StackOverflow):

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

Funciona tanto en FF e IE.

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

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

El tipo de FocusEvent casos han relatedTarget atributo, sin embargo, hasta la versión 47 de la FF, específicamente, este atributo devuelve null, del 48 ya funciona.

Usted puede ver más aquí.

También estoy tratando de hacer Autocompleter ignorar el desenfoque si un elemento específico de hacer clic y se tiene una solución de trabajo, pero sólo 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 se ajusta por defecto onBlur método de Autocompleter y comprueba si ignoreBlurEventElement parámetros se establece.si se establece, se comprueba cada vez para ver si hace clic elemento es ignoreBlurEventElement o no.Si es así, Autocompleter no cal onBlur, otra cosa que llama a onBlur.El único problema con esto es que sólo funciona en Firefox, debido a explicitOriginalTarget propiedad es Mozilla específicos .Ahora estoy tratando de encontrar una manera diferente de utilizar explicitOriginalTarget.La solución que usted ha mencionado requiere agregar onclick comportamiento manualmente para el elemento.Si no puedo gestionar para resolver explicitOriginalTarget problema, supongo que voy a seguir su solución.

Se puede revertir lo que está leyendo y cuando?Esto es, si usted recuerda lo que era borrosa última:

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

y, a continuación, en el onClick para su palmo, una llamada a la función() con ambos objetos:

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

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

Usar algo como esto:

var myVar = null;

Y a continuación, dentro de su función:

myVar = fldID;

Y luego:

setTimeout(setFocus,1000)

Y luego:

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>

creo que no sibe, con IE puede probar a usar window.event.toElement, pero dosn no funciona con firefox!

Como se señaló en esta respuesta, puede comprobar el valor de document.activeElement. document es una variable global, por lo que no tiene que hacer ninguna magia para usarlo en el onBlur controlador:

function myOnBlur(e) {
  if(document.activeElement ===
       document.getElementById('elementToCheckForFocus')) {
    // Focus went where we expected!
    // ...
  }
}
  • documento.activeElement podría ser un nodo primario (por ejemplo, cuerpo nodo porque se está en una fase temporal de conmutación de un objetivo a otro), por lo que no es utilizable para tu alcance
  • ev.explicitOriginalTarget no es valorado siempre

Así que la mejor manera es utilizar onclick en el cuerpo de eventos para la comprensión indirectamente su nodo(evento.de destino) es de desenfoque

Editar: Un hacky manera de hacerlo sería crear una variable que sigue la pista de enfoque para cada elemento que te importan.Por lo tanto, si usted atención a que "myInput' perdido el foco, establecer una variable de la misma en el foco.

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

Original Respuesta:Usted puede pasar 'esta' a la función.

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

Sugiero el uso de variables globales blurfrom y blurto.A continuación, configure todos los elementos que te importa a ceder su posición en el DOM para la variable blurfrom cuando se pierda el foco.Además, configurarlos de manera que ganando enfoque establece la variable blurto a su posición en el DOM.A continuación, podría utilizar otra función en conjunto para analizar la blurfrom y blurto de datos.

tenga en cuenta, que la solución con explicitOriginalTarget no funciona para el texto de entrada de texto entrada de salta.

intente reemplazar los botones con el texto siguiente-entradas y verás 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">

He estado jugando con esta misma característica y descubrí que la FF, IE, Chrome y Opera tienen la capacidad de proporcionar la fuente de los elementos de un evento.Yo no he probado Safari, pero mi conjetura es 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;
    }
    //...
});

No me gusta el uso de tiempo de espera cuando la codificación de javascript así que me gustaría hacerlo de la manera opuesta de Michiel Borkent.(No intente el código detrás, pero usted debe tener una idea).

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

En la cabeza algo así como que

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

Usted puede arreglar es decir, con :

 event.currentTarget.firstChild.ownerDocument.activeElement

Parece que "explicitOriginalTarget" para FF.

Antoine Y J

Escribí un solución alternativa cómo hacer que cualquier elemento seleccionable y "blurable".

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

el.addEventListener("keydown", function(e) {
  e.preventDefault();
  e.stopPropagation();
});

el.addEventListener("blur", cbBlur);
el.contentEditable = true;

DEMO

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


Relacionado con:Yo estaba buscando una solución para VueJs, así que para aquellos que interesados/curioso cómo implementar dicha funcionalidad mediante Vue Seleccionable de la directiva, por favor echa un vistazo.

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

Puedo probar en Internet Explorer 9 y no se admite.

$("#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
     }
});

Comentario de su prueba en otras versiones de internet explorer.

Yo sólo veo hacks en las respuestas, pero en realidad hay un builtin solución muy fácil de usar :Básicamente, usted puede capturar el enfoque elemento como este:

const focusedElement = document.activeElement

https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/activeElement

De esta manera:

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

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

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

Editar:lo siento.No entendí la pregunta.


Creo que es fácilmente posible a través de jquery pasando la referencia del campo causando el evento onblur en "este".
Por ejemplo,

<input type="text" id="text1" onblur="showMessageOnOnblur(this)">

function showMessageOnOnblur(field){
    alert($(field).attr("id"));
}

Gracias
Monika

Se podría hacer así:

<script type="text/javascript">
function myFunction(thisElement) 
{
    document.getElementByName(thisElement)[0];
}
</script>
<input type="text" name="txtInput1" onBlur="myFunction(this.name)"/>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top