Tengo un campo de entrada que abre 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 eliminarse.
- Si, más específicamente, el usuario hace clic en un div dentro del menú, el menú debe eliminarse y debe producirse un procesamiento especial en función de qué div se hizo clic.
Aquí está mi implementación:
El campo de entrada tiene un onblur()
evento que elimina el menú (estableciendo su padre innerHTML
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 onclick()
eventos que ejecutan el procesamiento especial.
El problema es que los onclick()
eventos nunca se activan cuando se hace clic en el menú, porque el campo de entrada se onblur()
activa primero y elimina el menú, incluidos los onclick()
s!
Resolví el problema dividiendo los divs del menú onclick()
en onmousedown()
y onmouseup()
eventos y estableciendo una bandera global al presionar el mouse hacia abajo que se borra al presionar el mouse hacia arriba, similar a lo que se sugirió en esta respuesta . Debido a que se onmousedown()
dispara antes onblur()
, la bandera se activará onblur()
si se hizo clic en uno de los divs del menú, pero no si se hizo en otro lugar de la pantalla. Si se hizo clic en el menú, vuelvo inmediatamente onblur()
sin eliminar el menú, luego espero a onclick()
que se active, momento en el que puedo eliminar el menú de forma segura.
¿Existe una solución más elegante?
El código se parece a esto:
<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;
...
}