我有一个文本输入框,其中弹出一个自定义下拉菜单。我希望它能够实现以下功能:
- 当用户点击输入框外部的任何地方时,菜单应该被移除。
- 更具体地说,如果用户点击菜单中的某个div,则菜单应该被删除,并且应基于所点击的div执行特殊处理。
以下是我的实现:
输入字段具有onblur()
事件,当用户在输入字段外点击时通过将其父元素的innerHTML
设置为空字符串来删除菜单。菜单中的div还具有onclick()
事件,用于执行特殊处理。
问题在于,当菜单被单击时,onclick()
事件永远不会触发,因为先触发了输入字段的onblur()
并删除了菜单,包括onclick()
!
我通过将菜单div的onclick()
事件拆分为onmousedown()
和onmouseup()
事件,并在鼠标按下时设置全局标志,在鼠标松开时清除标志解决了这个问题,类似于这个答案中建议的方式。因为onmousedown()
在onblur()
之前触发,如果单击了菜单div之一,则标志将在onblur()
中设置,但如果在屏幕上的其他地方单击,则不会设置。如果单击了菜单,则我立即从onblur()
返回而不删除菜单,然后等待onclick()
触发,在此时可以安全地删除菜单。
是否有更优雅的解决方案?
代码大致如下:
<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;
...
}
onmousedown
在onblur
之前执行。在Firefox、Chrome和Internet Explorer中测试过。 - Tonatioevent.preventDefault()
的onMouseDown
,以及使用您想要执行的操作的onClick
。 - Conal Da Costa