JavaScript:检查鼠标按钮是否按下?
有没有办法检测 JavaScript 中鼠标按钮当前是否按下?
我知道“mousedown”事件,但这不是我需要的。 按下鼠标按钮一段时间后,我希望能够检测它是否仍然被按下。
这可能吗?
Is there a way to detect if a mouse button is currently down in JavaScript?
I know about the "mousedown" event, but that's not what I need. Some time AFTER the mouse button is pressed, I want to be able to detect if it is still pressed down.
Is this possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(17)
关于 Pax 的解决方案:如果用户有意或无意地单击多个按钮,该解决方案将不起作用。 不要问我怎么知道的:-(。
正确的代码应该是这样的:
通过这样的测试:
如果你想知道按下了什么按钮,准备好让 mouseDown 成为一个计数器数组,并分别对它们进行计数单独的按钮:
现在您可以检查到底按下了哪些按钮:
现在请注意,上面的代码仅适用于向您传递从 0 开始的按钮编号的符合标准的浏览器 IE 使用当前按下的按钮的位掩码:
因此请相应地调整您的代码!
记住:IE 使用。一个名为…“event”的全局事件对象。
顺便说一句,IE 有一个对您的情况很有用的功能:当其他浏览器仅针对鼠标按钮事件(onclick、onmousedown 和 onmouseup)发送“button”时,IE 会使用 onmousemove 发送它因此,当您需要知道按钮状态时,您可以开始侦听 onmousemove,并在获得后立即检查 evt.button - 现在您知道按下了哪些鼠标按钮:
当然,如果她装死,您什么也得不到。没有移动。
相关链接:
< strong>更新#1:我不知道为什么我继承了 document.body-style 的代码。 最好将事件处理程序直接附加到文档。
Regarding Pax' solution: it doesn't work if user clicks more than one button intentionally or accidentally. Don't ask me how I know :-(.
The correct code should be like that:
With the test like this:
If you want to know what button is pressed, be prepared to make mouseDown an array of counters and count them separately for separate buttons:
Now you can check what buttons were pressed exactly:
Now be warned that the code above would work only for standard-compliant browsers that pass you a button number starting from 0 and up. IE uses a bit mask of currently pressed buttons:
So adjust your code accordingly! I leave it as an exercise.
And remember: IE uses a global event object called … "event".
Incidentally IE has a feature useful in your case: when other browsers send "button" only for mouse button events (onclick, onmousedown, and onmouseup), IE sends it with onmousemove too. So you can start listening for onmousemove when you need to know the button state, and check for evt.button as soon as you got it — now you know what mouse buttons were pressed:
Of course you get nothing if she plays dead and not moving.
Relevant links:
Update #1: I don't know why I carried over the document.body-style of code. It will be better to attach event handlers directly to the document.
这是一个老问题,这里的答案似乎主要提倡使用
mousedown
和mouseup
来跟踪按钮是否被按下。 但正如其他人指出的那样,mouseup 仅在浏览器中执行时才会触发,这可能会导致丢失按钮状态的跟踪。但是, MouseEvent (现在)指示当前按下了哪些按钮:
MouseEvent.buttons
对于 SafariMouseEvent.buttons
MouseEvent.buttons
11.1(iOS 上为 11.3),使用MouseEvent.which< /code>
(对于 Safari,
buttons
未定义)注意:which
使用与buttons
不同的数字来进行右键单击和中键单击。当在
document
上注册时,一旦光标重新进入浏览器,mousemove
就会立即触发,因此如果用户在外部释放鼠标,那么一旦鼠标返回,状态就会更新里面。一个简单的实现可能如下所示:
该代码跟踪鼠标主按钮(通常是左侧)的状态,忽略其他鼠标按钮的状态。
如果需要更复杂的场景(不同的按钮/多个按钮/控制键),请查看
MouseEvent
文档。This is an old question, and the answers here seem to mostly advocate for using
mousedown
andmouseup
to keep track of whether a button is pressed. But as others have pointed out,mouseup
will only fire when performed within the browser, which can lead to losing track of the button state.However, MouseEvent (now) indicates which buttons are currently pushed:
MouseEvent.buttons
MouseEvent.which
(buttons
will be undefined for Safari) Note:which
uses different numbers frombuttons
for Right and Middle clicks.When registered on
document
,mousemove
will fire immediately as soon as the cursor reenters the browser, so if the user releases outside then the state will be updated as soon as they mouse back inside.A simple implementation might look like:
That code tracks the state of the primary mouse button (typically the left), ignoring the state of other mouse buttons.
If more complicated scenarios are required (different buttons/multiple buttons/control keys), check out the
MouseEvent
docs.我认为最好的方法是保留您自己的鼠标按钮状态记录,如下所示:
然后在您的代码中:
I think the best approach to this is to keep your own record of the mouse button state, as follows:
and then, later in your code:
解决方案并不好。
人们可以在文档上“mousedown”,然后在浏览器外“mouseup”,在这种情况下,浏览器仍会认为鼠标已按下。
唯一好的解决方案是使用 IE.event 对象。
the solution isn't good.
one could "mousedown" on the document, then "mouseup" outside the browser, and on this case the browser would still be thinking the mouse is down.
the only good solution is using IE.event object.
我知道这是一篇旧文章,但我认为使用鼠标向上/向下跟踪鼠标按钮感觉有点笨拙,所以我找到了一个可能会吸引某些人的替代方案。
:active 选择器处理鼠标单击比鼠标向上/向下要好得多,您只需要一种在 onmousemove 事件中读取该状态的方法。 为此,我需要作弊并依赖于默认光标是“自动”的事实,我只需将其更改为“默认”,这是默认情况下自动选择的。
您可以使用 getComputedStyle 返回的对象中的任何内容,您可以将其用作标志,而不会破坏页面的外观,例如边框颜色。
我想在 :active 部分设置我自己的用户定义样式,但我无法让它工作。 如果可以的话就更好了。
I know this is an old post, but I thought the tracking of mouse button using mouse up/down felt a bit clunky, so I found an alternative that may appeal to some.
The :active selector handles the mouse click much better than mouse up/down, you just need a way of reading that state in the onmousemove event. For that I needed to cheat and relied on the fact that the default cursor is "auto" and I just change it to "default", which is what auto selects by default.
You can use anything in the object that is returned by getComputedStyle that you can use as a flag without upsetting the look of your page e.g. border-color.
I would have liked to set my own user defined style in the :active section, but I couldn't get that to work. It would be better if it's possible.
如果您正在使用现有鼠标事件处理程序的复杂页面中工作,我建议在捕获上处理事件(而不是冒泡)。 为此,只需将
addEventListener
的第三个参数设置为true
即可。此外,您可能需要检查
event.which
以确保您正在处理实际的用户交互而不是鼠标事件,例如elem.dispatchEvent(new Event('mousedown')).
将处理程序添加到文档(或窗口)而不是 document.body 中很重要,因为它可以确保仍然记录窗口外部的 mouseup 事件。
If you're working within a complex page with existing mouse event handlers, I'd recommend handling the event on capture (instead of bubble). To do this, just set the 3rd parameter of
addEventListener
totrue
.Additionally, you may want to check for
event.which
to ensure you're handling actual user interaction and not mouse events, e.g.elem.dispatchEvent(new Event('mousedown'))
.Add the handler to document (or window) instead of document.body is important b/c it ensures that mouseup events outside of the window are still recorded.
如果其他人遇到这种情况,您可以将
.matches
与:active
选择器一起使用:In case someone else runs into this, you can use
.matches
with the:active
selector:以下代码片段将在 document.body 中发生 mouseDown 事件 2 秒后尝试执行“doStuff”函数。 如果用户抬起按钮,则会发生 mouseUp 事件并取消延迟执行。
我建议使用某种跨浏览器事件附加方法 - 显式设置 mousedown 和 mouseup 属性是为了简化示例。
The following snippet will attempt to execute the "doStuff" function 2 seconds after the mouseDown event occurs in document.body. If the user lifts up the button, the mouseUp event will occur and cancel the delayed execution.
I'd advise using some method for cross-browser event attachment - setting the mousedown and mouseup properties explicitly was done to simplify the example.
使用 MouseEvent api,检查按下的按钮,如果任何:
返回:
Using the MouseEvent api, to check the pressed button, if any:
Return:
您可以结合@Pax和我的答案来获取鼠标按下的持续时间:
然后:
You can combine @Pax and my answers to also get the duration that the mouse has been down for:
Then later:
您需要处理 MouseDown 和 MouseUp 并设置一些标志或其他东西来跟踪它“稍后”......:(
You need to handle the MouseDown and MouseUp and set some flag or something to track it "later down the road"... :(
简短而甜蜜,
我不确定为什么以前的答案都不适合我,但我突然想到了这个解决方案。 它不仅有效,而且非常优雅:
添加到 body 标记:
如果
down
等于1
,则测试并执行myfunction()
:Short and sweet
I'm not sure why none of the previous answers worked for me, but I came up with this solution during a eureka moment. It not only works, but it is also most elegant:
Add to body tag:
Then test and execute
myfunction()
ifdown
equals1
:使用 jQuery,以下解决方案甚至可以处理“拖出页面然后释放的情况”。
我不知道它如何处理多个鼠标按钮。
如果有一种方法可以在窗口外部开始单击,然后将鼠标移入窗口,那么这可能也无法正常工作。
Using jQuery, the following solution handles even the "drag off the page then release case".
I don't know how it handles multiple mouse buttons.
If there were a way to start the click outside the window, then bring the mouse into the window, then this would probably not work properly there either.
正如@Jack所说,当
mouseup
发生在浏览器窗口之外时,我们不知道它......这段代码(几乎)对我有用:
不幸的是,我不会得到
mouseup其中一种情况会发生
事件:As said @Jack, when
mouseup
happens outside of browser window, we are not aware of it...This code (almost) worked for me:
Unfortunately, I won't get the
mouseup
event in one of those cases:这个跨浏览器版本对我来说效果很好。
this cross-browser version works fine for me.
下面的 jQuery 示例中,当鼠标悬停在 $('.element') 上时,颜色会根据按下的鼠标按钮而变化。
Below jQuery example, when mouse is over $('.element'), color is changing depending on which mouse button is pressed.
好吧,您无法在事件发生后检查它是否已按下,但您可以检查它是否已按下...如果它已按下...则意味着不再按下:P lol
因此用户按下了按钮(onMouseDown 事件) ...之后,您检查是否已启动(onMouseUp)。 虽然它还没有启动,但您可以做您需要做的事情。
Well, you can't check if it's down after the event, but you can check if it's Up... If it's up.. it means that no longer is down :P lol
So the user presses the button down (onMouseDown event) ... and after that, you check if is up (onMouseUp). While it's not up, you can do what you need.