问题描述
我有一个输入字段,它会显示一个自定义下拉菜单.我想要以下功能:
I have an input field that brings up a custom drop-down menu. I would like the following functionality:
- 当用户点击输入框以外的任何地方时,菜单应该被移除.
- 更具体地说,如果用户单击菜单内的 div,则应删除菜单,并且应根据单击的 div 进行特殊处理.
- 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.
这是我的实现:
输入字段有一个 onblur()
事件,当用户在输入字段外单击时,该事件会删除菜单(通过将其父级的 innerHTML
设置为空字符串).菜单中的 div 也有执行特殊处理的 onclick()
事件.
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.
问题是当点击菜单时 onclick()
事件永远不会触发,因为输入字段的 onblur()
会首先触发并删除菜单,包括onclick()
s!
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!
我通过将菜单 div 的 onclick()
拆分为 onmousedown()
和 onmouseup()
事件并设置一个全局事件来解决问题鼠标按下时的标志,鼠标抬起时清除,类似于 this answer 中的建议.因为 onmousedown()
在 onblur()
之前触发,所以如果单击菜单 div 之一,标志将在 onblur()
中设置,但是不是如果屏幕上的其他地方是.如果单击了菜单,我会立即从 onblur()
返回而不删除菜单,然后等待 onclick()
触发,此时我可以安全地删除菜单.
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?
代码如下所示:
<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;
...
}
推荐答案
我遇到了和你一模一样的问题,我的 UI 和你描述的完全一样.我通过简单地将菜单项的 onClick
替换为 onMouseDown
解决了这个问题.我什么也没做;没有 onMouseUp
,没有标志.这解决了这个问题,让浏览器根据这些事件处理程序的优先级自动重新排序,而无需我做任何额外的工作.
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?
这篇关于onclick() 和 onblur() 排序问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!