I have an input field that brings up a custom drop-down menu. I would like the following functionality:
- When the user clicks anywhere outside the input field, the menu should be removed.
- If, more specifically, the user clicks on a div inside the menu, the menu should be removed, and special processing should occur based on which div was clicked.
Here is my implementation:
The input field has an onblur()
event which deletes the menu (by setting its parent's innerHTML
to an empty string) whenever the user clicks outside the input field. The divs inside the menu also have onclick()
events which execute the special processing.
The problem is that the onclick()
events never fire when the menu is clicked, because the input field's onblur()
fires first and deletes the menu, including the onclick()
s!
I solved the problem by splitting the menu divs' onclick()
into onmousedown()
and onmouseup()
events and setting a global flag on mouse down which is cleared on mouse up, similar to what was suggested in this answer. Because onmousedown()
fires before onblur()
, the flag will be set in onblur()
if one of the menu divs was clicked, but not if somewhere else on the screen was. If the menu was clicked, I immediately return from onblur()
without deleting the menu, then wait for the onclick()
to fire, at which point I can safely delete the menu.
Is there a more elegant solution?
The code looks something like this:
<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;
...
}
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…