J'ai un champ de saisie qui fait apparaître un menu déroulant personnalisé. Je souhaite la fonctionnalité suivante:
- Lorsque l'utilisateur clique n'importe où en dehors du champ de saisie, le menu doit être supprimé.
- Si, plus spécifiquement, l'utilisateur clique sur un div dans le menu, le menu doit être supprimé et un traitement spécial doit avoir lieu en fonction du div sur lequel l'utilisateur a cliqué.
Voici ma mise en œuvre:
Le champ de saisie a un onblur()
événement qui supprime le menu (en définissant son parent innerHTML
sur une chaîne vide) chaque fois que l'utilisateur clique en dehors du champ de saisie. Les div à l'intérieur du menu ont également des onclick()
événements qui exécutent le traitement spécial.
Le problème est que les onclick()
événements ne se déclenchent jamais lorsque l'utilisateur clique sur le menu, car le champ de saisie se onblur()
déclenche en premier et supprime le menu, y compris le onclick()
s!
J'ai résolu le problème en se divisant le menu divs' onclick()
en onmousedown()
et des onmouseup()
événements et la fixation d' un indicateur global sur le bas de la souris qui est effacée sur souris vers le haut, semblable à ce qui a été suggéré dans cette réponse . Parce que se onmousedown()
déclenche avant onblur()
, le drapeau sera activé onblur()
si l'un des divs de menu a été cliqué, mais pas si quelque part ailleurs sur l'écran était. Si le menu a été cliqué, je reviens immédiatement de onblur()
sans supprimer le menu, puis attendez que le onclick()
se déclenche, à quel point je peux supprimer le menu en toute sécurité.
Existe-t-il une solution plus élégante?
Le code ressemble à ceci:
<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;
...
}