javascript - asp - Problema de ordenamiento de onclick() y onblur()
onblur jquery (5)
Estaba teniendo exactamente el mismo problema que tú, mi interfaz de usuario está diseñada exactamente como lo describes. Resolví el problema simplemente reemplazando el onClick por los elementos del menú con un onMouseDown. No hice nada más; no onMouseUp, sin banderas. Esto resolvió el problema al permitir que el navegador reordenara automáticamente en función de la prioridad de estos controladores de eventos, sin ningún trabajo adicional de mi parte.
¿Hay alguna razón por la cual esto no habría funcionado para ti?
Tengo un campo de entrada que muestra un menú desplegable personalizado. Me gustaría la siguiente funcionalidad:
- Cuando el usuario hace clic en cualquier lugar fuera del campo de entrada, el menú debe ser eliminado.
- Si, más específicamente, el usuario hace clic en un div dentro del menú, el menú debe ser eliminado, y el procesamiento especial debe ocurrir en función de qué div se hizo clic.
Aquí está mi implementación:
El campo de entrada tiene un evento onblur()
que elimina el menú (estableciendo innerHTML
su padre en una cadena vacía) cada vez que el usuario hace clic fuera del campo de entrada. Los divs dentro del menú también tienen eventos onclick()
que ejecutan el procesamiento especial.
El problema es que los eventos onclick()
nunca se disparan cuando se hace clic en el menú, porque el campo de entrada onblur()
dispara primero y elimina el menú, incluido el onclick()
s.
Resolví el problema dividiendo el menú divs '' onclick()
en eventos onmousedown()
y onmouseup()
y estableciendo un indicador global en el mouse que se borra en el mouse hacia arriba, similar a lo que se sugirió en esta respuesta . Debido a que onmousedown()
dispara antes de onblur()
, la bandera se establecerá en onblur()
si se hizo clic en uno de los onblur()
de menú, pero no si en otro lugar de la pantalla se hizo clic. Si se hizo clic en el menú, inmediatamente regreso de onblur()
sin borrar el menú, luego espero a que onclick()
dispare, momento en el cual puedo eliminar el menú de manera segura.
¿Hay una solución más elegante?
El código se ve así:
<div class="menu" onmousedown="setFlag()" onmouseup="doProcessing()">...</div>
<input id="input" onblur="removeMenu()" ... />
var mouseflag;
function setFlag() {
mouseflag = true;
}
function removeMenu() {
if (!mouseflag) {
document.getElementById(''menu'').innerHTML = '''';
}
}
function doProcessing(id, name) {
mouseflag = false;
...
}
Puede usar una función setInterval
dentro de su controlador onBlur
, así:
<input id="input" onblur="removeMenu()" ... />
function removeMenu() {
setInterval(function(){
if (!mouseflag) {
document.getElementById(''menu'').innerHTML = '''';
}
}, 0);
}
la función setInterval
eliminará tu función onBlur
de la pila de llamadas, agrega porque estableces el tiempo en 0, esta función se invocará inmediatamente después de que termine el otro controlador de eventos
Reemplace en onfocus
con onfocus
. Entonces este evento se activará cuando el foco esté dentro del cuadro de texto.
Reemplazar en onmouseup
con onblur
. En el momento en que saques tu foco de la caja de texto, se ejecutará onblur.
Supongo que esto es lo que podrías necesitar.
ACTUALIZAR :
cuando ejecute su función en el foco -> elimine las clases que aplicará en onblur y agregue las clases que desea que se ejecuten enfocus
y
cuando ejecuta su función onblur -> elimina las clases que aplicará enfocus y agrega las clases que desea que se ejecuten enblur
No veo ninguna necesidad de variables de bandera.
ACTUALIZACIÓN 2:
Puede usar los eventos onmouseout y onmouseover
onmouseover: detecta cuando el cursor está sobre él.
onmouseout: detecta cuando el cursor se va.
Una solución más elegante (pero probablemente menos eficiente):
En lugar de utilizar la información de entrada para eliminar el menú, use document.onclick
, que se onblur
después de onblur
.
Sin embargo, esto también significa que el menú se elimina cuando se hace clic en la entrada en sí misma, que es un comportamiento no deseado. Establezca una input.onclick
event.stopPropagation()
input.onclick
con event.stopPropagation()
para evitar la propagación de clics al evento de clic de documento.
cambiar onclick por onfocus
incluso si onblur y onclick no se llevan muy bien, pero obviamente onfocus y sí onblur. ya que incluso después de que el menú está cerrado, el enfoque sigue siendo válido para el elemento al que se hace clic dentro.
Lo hice y funcionó.