检查鼠标按钮是否向下?

有没有一种方法可以检测当前 JavaScript 中鼠标按钮是否处于关闭状态?

我知道鼠标掉下来的事,但那不是我想要的。在鼠标按钮被按下一段时间后,我希望能够检测它是否仍然被按下。

这可能吗?

220956 次浏览

活动结束后你不能检查它是不是坏了但你可以检查它是不是坏了。.这意味着不再下降:

因此,用户按下按钮(onMouseDown 事件) ... 然后,检查是否向上(onMouseUp)。虽然它不是,你可以做你需要的。

下面的代码片段将尝试在 document.body 中发生 mouseDown 事件2秒后执行“ doStuff”函数。如果用户提起按钮,则会发生 mouseUp 事件并取消延迟的执行。

我建议使用一些跨浏览器事件附件的方法-显式设置 mousedown 和 mouseup 属性以简化示例。

function doStuff() {
// does something when mouse is down in body for longer than 2 seconds
}


var mousedownTimeout;


document.body.onmousedown = function() {
mousedownTimeout = window.setTimeout(doStuff, 2000);
}


document.body.onmouseup = function() {
window.clearTimeout(mousedownTimeout);
}

我认为最好的方法是保留您自己的鼠标按钮状态记录,如下所示:

var mouseDown = 0;
document.body.onmousedown = function() {
mouseDown = 1;
}
document.body.onmouseup = function() {
mouseDown = 0;
}

然后,在后面的代码中:

if (mouseDown == 1) {
// the mouse is down, do what you have to do.
}

你可以把@Pax 和我的答案结合起来,得到鼠标停机的时间:

var mousedownTimeout,
mousedown = 0;


document.body.onmousedown = function() {
mousedown = 0;
window.clearInterval(mousedownTimeout);
mousedownTimeout = window.setInterval(function() { mousedown += 200 }, 200);
}


document.body.onmouseup = function() {
mousedown = 0;
window.clearInterval(mousedownTimeout);
}

后来:

if (mousedown >= 2000) {
// do something if the mousebutton has been down for at least 2 seconds
}

关于 帕克斯的解决方案: 如果用户有意或无意地点击多个按钮,它就不起作用。不要问我怎么知道的:。

正确的代码应该是这样的:

var mouseDown = 0;
document.body.onmousedown = function() {
++mouseDown;
}
document.body.onmouseup = function() {
--mouseDown;
}

通过这样的测试:

if(mouseDown){
// crikey! isn't she a beauty?
}

如果你想知道按下的是什么按钮,准备好让鼠标下移到一个计数器数组中,然后分别对不同的按钮进行计数:

// let's pretend that a mouse doesn't have more than 9 buttons
var mouseDown = [0, 0, 0, 0, 0, 0, 0, 0, 0],
mouseDownCount = 0;
document.body.onmousedown = function(evt) {
++mouseDown[evt.button];
++mouseDownCount;
}
document.body.onmouseup = function(evt) {
--mouseDown[evt.button];
--mouseDownCount;
}

现在你可以检查到底按了哪些按钮:

if(mouseDownCount){
// alright, let's lift the little bugger up!
for(var i = 0; i < mouseDown.length; ++i){
if(mouseDown[i]){
// we found it right there!
}
}
}

现在需要注意的是,上面的代码只适用于标准兼容的浏览器,这些浏览器会给你一个从0开始的按钮号。IE 使用了当前按下按钮的位掩码:

  • 0表示“没有按任何键”
  • 左边一个
  • 右边两个
  • 中间四个
  • 以及以上的任何组合,例如,5代表左 + 中

因此,相应地调整您的代码! 我把它作为一个练习。

记住: IE 使用一个全局事件对象,叫做... “事件”。

顺便说一句,IE 有一个特性在你的情况下很有用: 当其他浏览器发送“按钮”只为鼠标按钮事件(onclick,onmousedown,和 onmouseup) ,IE 发送它与 onmousemove。因此,当你需要知道按钮的状态时,你可以开始监听 onmousemove,一旦你得到它,你就可以检查 evt.Button ーー现在你知道按下了哪些鼠标按钮:

// for IE only!
document.body.onmousemove = function(){
if(event.button){
// aha! we caught a feisty little sheila!
}
};

如果她装死不动,你当然什么也得不到。

相关连结:

更新 # 1 : 我不知道为什么要继承 document.body 风格的代码。最好将事件处理程序直接附加到文档。

您需要处理 MouseDown 和 MouseUp,并设置一些标志或其他东西来跟踪它“稍后在路上”... : (

解决办法不好。 人们可以在文档上“鼠标向下”,然后在浏览器外面“鼠标向上”,在这种情况下,浏览器仍然会认为鼠标已经关闭。

唯一好的解决方案是使用 IE.event 对象。

简短而甜蜜

我不知道为什么以前的答案对我都不管用,但我在一个灵光一现的时刻想出了这个解决方案。它不仅有效,而且非常优雅:

添加到身体标签:

onmouseup="down=0;" onmousedown="down=1;"

然后测试并执行 myfunction(),如果 down等于 1:

onmousemove="if (down==1) myfunction();"
        var mousedown = 0;
$(function(){
document.onmousedown = function(e){
mousedown = mousedown | getWindowStyleButton(e);
e = e || window.event;
console.log("Button: " + e.button + " Which: " + e.which + " MouseDown: " + mousedown);
}


document.onmouseup = function(e){
mousedown = mousedown ^ getWindowStyleButton(e);
e = e || window.event;
console.log("Button: " + e.button + " Which: " + e.which + " MouseDown: " + mousedown);
}


document.oncontextmenu = function(e){
// to suppress oncontextmenu because it blocks
// a mouseup when two buttons are pressed and
// the right-mouse button is released before
// the other button.
return false;
}
});


function getWindowStyleButton(e){
var button = 0;
if (e) {
if (e.button === 0) button = 1;
else if (e.button === 1) button = 4;
else if (e.button === 2) button = 2;
}else if (window.event){
button = window.event.button;
}
return button;
}

这个跨浏览器版本对我来说很好用。

使用 jQuery,下面的解决方案甚至可以处理“从页面拖动然后发布情况”。

$(document).mousedown(function(e) {
mouseDown = true;
}).mouseup(function(e) {
mouseDown = false;
}).mouseleave(function(e) {
mouseDown = false;
});

我不知道它是如何处理多个鼠标按钮的。 如果有一种方法可以启动窗口外的点击,然后将鼠标带入窗口,那么这可能不会正常工作在那里。

在 jQuery 例子中,当鼠标位于 $(’. element’)上方时,颜色会根据鼠标按钮的不同而改变。

var clicableArea = {
init: function () {
var self = this;
('.element').mouseover(function (e) {
self.handlemouseClick(e, $(this));
}).mousedown(function (e) {
self.handlemouseClick(e, $(this));
});
},
handlemouseClick: function (e, element) {
if (e.buttons === 1) {//left button
element.css('background', '#f00');
}
if (e.buttons === 2) { //right buttom
element.css('background', 'none');
}
}
};
$(document).ready(function () {
clicableArea.init();
});

我知道这是一个老职位,但我认为跟踪鼠标按钮使用鼠标向上/向下感觉有点笨拙,所以我找到了一个替代方案,可能会吸引一些人。

<style>
div.myDiv:active {
cursor: default;
}
</style>


<script>
function handleMove( div ) {
var style = getComputedStyle( div );
if (style.getPropertyValue('cursor') == 'default')
{
// You're down and moving here!
}
}
</script>


<div class='myDiv' onmousemove='handleMove(this);'>Click and drag me!</div>

活动选择器处理鼠标点击要比鼠标上/下好得多,您只需要一种方法来读取 onmousemove 事件中的状态。为此,我需要作弊,并依赖于这样一个事实,即默认的光标是“ auto”,我只是将其更改为“ default”,这是 auto 默认选择的。

你可以使用 getComputedStyle 返回的对象中的任何东西作为标志,而不会影响页面的外观,例如边框颜色。

我本来想在: active 部分设置我自己的用户定义样式,但是我不能让它工作。如果可能的话会更好。

正如@Jack 所说,当 mouseup发生在浏览器窗口之外时,我们并不知道..。

这个代码(几乎)对我有效:

window.addEventListener('mouseup', mouseUpHandler, false);
window.addEventListener('mousedown', mouseDownHandler, false);

不幸的是,我不会得到 mouseup事件在这些情况之一:

  • 用户同时按下键盘键和鼠标键,在浏览器窗口外释放鼠标键,然后释放键。
  • 用户同时按下 鼠标按钮,释放一个鼠标按钮然后另一个,都在浏览器窗口之外。

如果使用现有的鼠标事件处理程序在复杂页面中工作,我建议在 捕捉上处理事件(而不是冒泡)。为此,只需将 addEventListener的第3个参数设置为 true

此外,您可能需要检查 event.which,以确保您正在处理实际的用户交互而不是鼠标事件,例如 elem.dispatchEvent(new Event('mousedown'))

var isMouseDown = false;


document.addEventListener('mousedown', function(event) {
if ( event.which ) isMouseDown = true;
}, true);


document.addEventListener('mouseup', function(event) {
if ( event.which ) isMouseDown = false;
}, true);

将处理程序添加到文档(或窗口)而不是 document.body 非常重要,它确保 mouseup 事件 在窗外仍然被记录。

这是一个老问题,这里的答案似乎主要是提倡使用 mousedownmouseup来跟踪按钮是否被按下。但是正如其他人所指出的,mouseup只有在浏览器中执行时才会触发,这可能导致失去按钮状态的跟踪。

然而,鼠标事件(现在)指示当前按下的按钮:

  • 对于所有现代浏览器(包括 Safari v11.1 + [ v11.3 + on iOS ]) ,使用 MouseEvent.buttons
  • 对于 Safari < 11.1(iOS 上为11.3) ,使用 MouseEvent.which(对于 Safari,buttons将未定义)注意: which在右键和中键点击时使用与 buttons不同的数字。

当在 document上注册时,一旦光标重新进入浏览器,mousemove就会立即激活,所以如果用户在外面释放,那么当他们将鼠标移回到内部时,状态就会立即更新。

一个简单的实现可能是这样的:

var primaryMouseButtonDown = false;


function setPrimaryButtonState(e) {
var flags = e.buttons !== undefined ? e.buttons : e.which;
primaryMouseButtonDown = (flags & 1) === 1;
}


document.addEventListener("mousedown", setPrimaryButtonState);
document.addEventListener("mousemove", setPrimaryButtonState);
document.addEventListener("mouseup", setPrimaryButtonState);

该代码跟踪主鼠标按钮(通常在左侧)的状态,忽略其他鼠标按钮的状态。

如果需要更复杂的场景(不同的按钮/多个按钮/控制键) ,请查看 MouseEvent文档。

使用 鼠标事件 API 检查按下的按钮(如果有的话) :

// Mouse buttons
document.addEventListener('mousedown', e => console.log(e.buttons))
// Keyboard keys
document.addEventListener('keydown', e => console.log(e.key))

返回 :

表示一个或多个按钮的数字。用于多个按钮 同时按下,值被合并(例如,3是主 + 中学)。

0 : No button or un-initialized
1 : Primary button (usually the left button)
2 : Secondary button (usually the right button)
4 : Auxilary button (usually the mouse wheel button or middle button)
8 : 4th button (typically the "Browser Back" button)
16 : 5th button (typically the "Browser Forward" button)

如果其他人遇到这种情况,您可以使用 .matches:active选择器:

function mouseDown() {
return document.body.matches(":active");
}