Ho un campo di input che fa apparire un menu a discesa personalizzato. Vorrei la seguente funzionalità:
- Quando l'utente fa clic in un punto qualsiasi al di fuori del campo di input, il menu dovrebbe essere rimosso.
- Se, più specificamente, l'utente fa clic su un div all'interno del menu, il menu dovrebbe essere rimosso e dovrebbe avvenire un'elaborazione speciale in base a quale div è stato cliccato.
Ecco la mia implementazione:
Il campo di input ha un onblur()
evento che cancella il menu (impostando il suo genitore innerHTML
su una stringa vuota) ogni volta che l'utente fa clic al di fuori del campo di input. I div all'interno del menu hanno anche onclick()
eventi che eseguono l'elaborazione speciale.
Il problema è che gli onclick()
eventi non si attivano mai quando si fa clic sul menu, perché il campo di input viene onblur()
attivato per primo ed elimina il menu, incluso il messaggio di posta onclick()
elettronica!
Ho risolto il problema suddividendo il menu div onclick()
in onmousedown()
ed onmouseup()
events e impostando un flag globale al mouse down che viene cancellato al mouse up, simile a quanto suggerito in questa risposta . Poiché si onmousedown()
attiva prima onblur()
, il flag verrà impostato onblur()
se è stato fatto clic su uno dei div del menu, ma non se lo era da qualche altra parte sullo schermo. Se il menu è stato cliccato, torno immediatamente da onblur()
senza eliminare il menu, quindi aspetto onclick()
che si attivi, a quel punto posso eliminare in sicurezza il menu.
Esiste una soluzione più elegante?
Il codice ha un aspetto simile a questo:
<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;
...
}