onclick() and onblur() ordering issue

javascript, onblur, onclick

Solution

I was having the exact same issue as you, my UI is designed exactly as you describe. I solved the problem by simply replacing the `onClick` for the menu items with an `onMouseDown`. I did nothing else; no `onMouseUp`, no flags. This resolved the problem by letting the browser automatically re-order based on the priority of these event handlers, without any additional work from me.

Is there any reason why this wouldn't have also worked for you?

Problem

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; ... } ```

Original source

Related problems