javascript - foco - ¿El evento Blur deja de funcionar el evento click?
onblur javascript ejemplo (4)
Parece que el evento Blur impide que el controlador de eventos click funcione? Tengo un cuadro combinado donde las opciones solo aparecen cuando el campo de texto tiene foco. Elegir un enlace de opción debería causar un evento.
Tengo un ejemplo de violín aquí: http://jsfiddle.net/uXq5p/6/
Reproducir:
- Seleccione el cuadro de texto
- Los enlaces aparecen
- Haga clic en un enlace
- La falta de definición incluso ocurre y los enlaces desaparecen
- Nada más sucede.
Comportamiento esperado:
En el paso 5, después de que se produce el desenfoque, el clic incluso también debería disparar. ¿Cómo hago que eso suceda?
ACTUALIZAR:
Después de jugar con esto por un tiempo, parece que alguien ha hecho todo lo posible para evitar que un evento de clic ya ocurrido sea manejado si un evento de desenfoque hace que el elemento cliqueado no se pueda hacer clic.
Por ejemplo:
$(''#ShippingGroupListWrapper'').css(''left'',''-20px'');
funciona bien, pero
$(''#ShippingGroupListWrapper'').css(''left'',''-2000px'');
previene el evento click
Esto parece ser un error en Firefox, ya que hacer que un elemento no se pueda hacer clic debería evitar clics futuros , pero no cancelar los que ya se han producido cuando se podía hacer clic.
Otras cosas que evitan el procesamiento del clic:
$(''#ShippingGroupListWrapper'').css(''z-index'',''-20'');
$(''#ShippingGroupListWrapper'').css(''display'',''none'');
$(''#ShippingGroupListWrapper'').css(''visibility'',''hidden'');
$(''#ShippingGroupListWrapper'').css(''opacity'',''.5'');
He encontrado algunas otras preguntas en este sitio que están teniendo problemas similares. Parece que hay dos soluciones flotando:
Usa un retraso. Esto es malo porque crea una condición de carrera entre el ocultador y el controlador de eventos click. También es descuidado.
Usa el evento
mousedown
. Pero esta tampoco es una gran solución, ya que elclick
es el evento correcto para un enlace. El comportamiento delmousedown
es contra-intuitivo desde una perspectiva de UX, particularmente porque no se puede cancelar el clic moviendo el mouse fuera del elemento antes de soltar el botón.
Puedo pensar en algunos más.
3. Utilice mouseover
y mouseout
en el enlace para habilitar / deshabilitar el evento de desenfoque para el campo. Esto no funciona con el tabulado del teclado ya que el mouse no está involucrado.
4. La mejor solución sería algo así como:
$(''#ShippingGroup'').blur(function()
{
if($(document.activeElement) == $(''.ShippingGroupLinkList''))
return; // The element that now has focus is a link, do nothing
$(''#ShippingGroupListWrapper'').css(''display'',''none''); // hide it.
}
Desafortunadamente, $(document.activeElement)
parece devolver siempre el elemento del cuerpo, no el que se hizo clic. Pero tal vez si hubiera una manera confiable de saber ya sea 1. qué elemento ahora tiene foco o dos, qué elemento causó la borrosidad (no qué elemento se está difuminando) desde el manejador de desenfoque. Además, ¿hay algún otro evento (además del mousedown
) que se dispare antes del desenfoque?
4. La mejor solución sería algo así como:
$(''#ShippingGroup'').blur(function() { if($(document.activeElement) == $(''.ShippingGroupLinkList'')) return; // The element that now has focus is a link, do nothing $(''#ShippingGroupListWrapper'').css(''display'',''none''); // hide it. }
Desafortunadamente, $ (document.activeElement) parece devolver siempre el elemento del cuerpo, no el que se hizo clic. Pero tal vez si hubiera una manera confiable de saber ya sea 1. qué elemento ahora tiene foco o dos, qué elemento causó la borrosidad (no qué elemento se está difuminando) desde el manejador de desenfoque.
Lo que puede estar buscando es e.relatedTarget . Por lo tanto, al hacer clic en el enlace, e.relatedTarget
debe completarse con el elemento de enlace, por lo que en su controlador de desenfoque, puede elegir no ocultar el contenedor si el elemento seleccionado está dentro del contenedor (o compararlo directamente con el enlace):
$(''#ShippingGroup'').blur(function(e)
{
if(!e.relatedTarget || !e.currentTarget.contains(e.relatedTarget)) {
// Alt: (!e.relatedTarget || $(e.relatedTarget) == $(''.ShippingGroupLinkList''))
$(''#ShippingGroupListWrapper'').css(''display'',''none''); // hide it.
}
}
(Tal vez no sea compatible con Target en los navegadores anteriores para los eventos blur
, pero parece funcionar en los últimos Chrome, Firefox y Safari)
Podría intentar el evento mousedown
lugar de click
.
$(''.ShippingGroupLinkList'').live("mousedown", function(e) {
alert(''You wont see me if your cursor was in the text box'');
});
Claramente, esta no es la mejor solución ya que un evento de mousedown
no se logra de la misma manera para el usuario que un evento de click
. Desafortunadamente, el evento de blur
también cancelará los eventos de mouseup
.
Realizar una acción que debería ocurrir al click
en un mousedown
es un mal UX. En cambio, ¿de qué se compone un click
? Un mousedown
y un mouseup
.
Por lo tanto, detenga la propagación del evento mousedown
en el controlador de mousedown
y realice la acción en el manejador de mouseup
.
Un ejemplo en ReactJS:
<a onMouseDown={e => e.preventDefault()}
onMouseUp={() => alert("CLICK")}>
Click me!
</a>
click
desencadenantes de eventos después del blur
para que el enlace se oculte. En lugar de click
mousedown
, funcionará.
$(''.ShippingGroupLinkList'').live("mousedown", function(e) {
alert(''You wont see me if your cursor was in the text box'');
});
Otra alternativa es tener algún retraso antes de ocultar los enlaces en el evento de blur
. Depende de usted qué enfoque elegir.