onclick()和onblur()排序问题

1''*_*1'' 82 javascript onclick onblur

我有一个输入字段,显示自定义下拉菜单.我想要以下功能:

  • 当用户单击输入字段外的任何位置时,应删除菜单.
  • 更具体地说,如果用户点击菜单中的div,则应删除菜单,根据单击的div进行特殊处理.

这是我的实现:

输入字段有一个onblur()事件,innerHTML只要用户在输入字段外单击,就会删除菜单(通过将其父项设置为空字符串).菜单中的div也有onclick()执行特殊处理的事件.

问题是onclick()单击菜单时事件永远不会触发,因为输入字段onblur()首先触发并删除菜单,包括onclick()s!

我解决了这个问题,将菜单div onclick()分成' onmousedown()onmouseup()事件,并在鼠标按下时设置一个全局标志,鼠标向上清除,类似于本答案中的建议.因为onmousedown()之前触发onblur(),onblur()如果单击其中一个菜单div ,则会设置标志,但如果屏幕上的其他位置没有,则不会.如果单击菜单,我立即返回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;
    ...
}
Run Code Online (Sandbox Code Playgroud)

joh*_*ers 150

我遇到了与你完全相同的问题,我的UI设计与你描述完全一样.我通过简单地用onMouseDown替换菜单项的onClick来解决问题.我什么都没做; 没有onMouseUp,没有标志.这解决了问题,让浏览器根据这些事件处理程序的优先级自动重新排序,而无需我的任何额外工作.

有什么理由说这对你没有用吗?

  • 值得注意的是,这确实有点自然地改变了行为 - 然后在鼠标按下而不是鼠标向上处理点击交互.对于大多数可能没问题的人(在这种情况下自我包括)但有一些缺点.最值得注意的是,我经常点击然后拖动按钮,如果我被错误点击,这可以防止onclick被调用 - 如果按钮执行非纯函数(删除,发布等),你可能想要保留它并使用标志方法. (7认同)
  • 这实际上有效.我在FF中测试了它,它的功效就像魅力一样. (3认同)
  • 有用。好像在执行onblur之前先执行了onmousedown,然后在Firefox,Chrome和Internet Explorer中进行了测试。 (3认同)
  • 当您设置 mouseDown 而不是 onClick 时,可访问性如何,您会杀死所有 &lt;button&gt; 元素的可访问性:/ (3认同)
  • @ian-macfarlane 下面列出的答案是处理此问题的正确方法。总结...`onMouseDown` 与 `event.preventDefault()` 和 `onClick` 以及您想要的操作。 (3认同)

Ian*_*ane 6

onClick不应替换为onMouseDown

尽管此方法有些奏效,但两者在本质上是不同的事件,在用户眼中具有不同的期望。在这种情况下,使用onMouseDown而不是onClick会破坏软件的可预测性。因此,这两个事件是不可互换的。

举例说明:意外单击按钮时,用户希望能够按住鼠标单击,将光标拖到元素外,然后释放鼠标按钮,最终不会采取任何措施。onClick做这个。onMouseDown不允许用户按住鼠标,而是立即触发操作,而无需用户追索。onClick是我们期望在计算机上触发操作的标准。

在这种情况下,调用event.preventDefault()onMouseDown事件。默认情况下,默认情况下onMouseDown会导致模糊事件,preventDefault调用时不会这样做。然后,onClick将有机会被称为。仅在之后,模糊事件仍然会发生onClick

毕竟,onClick事件的组合onMouseDownonMouseUp,当且仅当它们都发生在同一单元内。

  • 这对我来说是完美的解决方案,评论是完全正确的 - 替换 onMouseDown 会让用户体验感到困惑。已经投票了。 (11认同)
  • 这应该是正确的答案。感谢您发布此内容 (7认同)
  • 如果我在“onMouseDown”事件上使用“event.preventDefault()”,则不会调用“onFocus”事件 (5认同)
  • 值得注意的是,这也有一些小的副作用,例如无法通过在元素内单击来选择文本。想不出太多这会成为问题的案例,只是感觉有点有趣。 (2认同)