jQuery:在mousemove事件期间检测按下的鼠标按钮


71

我试图检测用户在jQuery下的mousemove事件期间按下的鼠标按钮-如果有的话,但是我得到的结果不明确:

no button pressed:      e.which = 1   e.button = 0
left button pressed:    e.which = 1   e.button = 0
middle button pressed:  e.which = 2   e.button = 1
right button pressed:   e.which = 3   e.button = 2

码:

<!DOCTYPE html>
<html>
<head>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
</head>
<body>

<input id="whichkey" value="type something">
<div id="log"></div>
<script>$('#whichkey').bind('mousemove',function(e){ 
  $('#log').html(e.which + ' : ' +  e.button );
});  </script>

</body>
</html>

如何分辨按下鼠标左键和根本没有按钮之间的区别?


请说明您要做的更好的事情。鼠标进入然后向下按下然后向上移动然后退出将导致没有按钮?那么,mousedown,mouseenter,mouseexit,mouseup怎么样?您是否在询问是否在输入上移动了鼠标,是否记录了未按下任何按钮的事实?
Fresheyeball 2011年

我正在尝试突出显示页面中的文本。每个词都在自己的范围内。跨度元素上的mouseover +左按钮应突出显示它,而mouseover + right的按钮应取消突出显示它。
塞巴斯蒂安·格里戈诺利

Answers:


63

您可以编写一些代码来跟踪鼠标左键的状态,并使用一些小功能可以对事件中的事件变量进行预处理mousemove

要跟踪LMB的状态,请为mousedown和绑定事件到文档级别,mouseup然后检查e.which以设置或清除该标志。

预处理是通过tweakMouseMoveEvent()我的代码中的函数完成的。为了支持IE版本<9,必须检查是否在窗口外部释放了鼠标按钮,如果是,则清除该标志。然后,您可以更改传递的事件变量。如果e.which最初是1(没有按钮或LMB),并且没有按下左按钮的当前状态,则将其设置e.which0,并在其余mousemove事件中使用该按钮检查是否没有按下按钮。

mousemove在我的示例中,处理程序仅调用tweak函数,将当前事件变量传递通过,然后输出的值e.which

$(function() {
    var leftButtonDown = false;
    $(document).mousedown(function(e){
        // Left mouse button was pressed, set flag
        if(e.which === 1) leftButtonDown = true;
    });
    $(document).mouseup(function(e){
        // Left mouse button was released, clear flag
        if(e.which === 1) leftButtonDown = false;
    });

    function tweakMouseMoveEvent(e){
        // Check from jQuery UI for IE versions < 9
        if ($.browser.msie && !e.button && !(document.documentMode >= 9)) {
            leftButtonDown = false;
        }

        // If left button is not set, set which to 0
        // This indicates no buttons pressed
        if(e.which === 1 && !leftButtonDown) e.which = 0;
    }

    $(document).mousemove(function(e) {
        // Call the tweak function to check for LMB and set correct e.which
        tweakMouseMoveEvent(e);

        $('body').text('which: ' + e.which);
    });
});

在此处尝试现场演示:http : //jsfiddle.net/G5Xr2/


谢谢,我不知道为什么在IE中总是0。
Jethro Larson

不错的解决方案。如果子元素上发生mousedown事件怎么办?文档mousedown事件是否还会被触发?
史蒂夫·B

5
如果不在浏览器上释放按钮,mouseup将不会触发。
Ariel 2013年

3
警告: $.browser已弃用,并将与jQuery 1.9+一起使用。您将需要使用jquery migration插件才能使其再次运行。请参阅:stackoverflow.com/q/9638247/165673
Yarin 2013年

4
请注意,始终最好将mousedownmouseup侦听器附加到document,而不必将mousemove处理程序附加到同一元素。这是为了处理诸如将鼠标拖离元素边缘的情况。但这假设事件总是传播,并且正如@Ariel指出的那样,它不处理在浏览器外部释放的鼠标!mousemove无论鼠标按下什么,我都会一直在事件中寻找准确的鼠标按钮状态,就像键盘修改器状态一样。(我真的输入了吗?)
Michael Scheper 2014年

20

现在,大多数浏览器Safari除外 *)支持该MouseEvent.buttons属性(注意:复数“ button s ”),当按下鼠标左键时该属性为1:

$('#whichkey').bind('mousemove', function(e) { 
    $('#log').html('Pressed: ' + e.buttons);
});

https://jsfiddle.net/pdz2nzon/2

*)世界正在向前发展:
https//webkit.org/blog/8016/release-notes-for-safari-technology-preview-43/
https://trac.webkit.org/changeset/223264/webkit/
https://bugs.webkit.org/show_bug.cgi?id=178214


4
这个答案应该是可以接受的!来自懒惰供应商的浏览器可以从以下网站
yckart '16

1
来添加此答案,因为其他人不起作用。同意这个应该被接受的答案。
BoB3K

1
我使用的是最新的Firefox,并且在“ PointerEvent”处理程序中应该可以处理鼠标设备的event.buttons属性,因此数据不准确。我想知道准确提供这些标志有多复杂?我在C ++的本机平台上做得很好。
彼得

6

jQuery标准化了该which值,因此它将可在所有浏览器中使用。我敢打赌,如果您运行脚本,将会发现不同的e.button值。


我也这么想。可悲的是,which不告诉我是否按下了左按钮。
塞巴斯蒂安·格里戈诺利

我认为某些事件不会像其他事件那样处理按钮数据,请尝试添加全局变量并通过mousedown事件更改其值。
Mottie 2010年

你是对的。如果需要,请在单独的答案中回答,以便将其标记为正确。
塞巴斯蒂安·格里戈诺利

6
如果鼠标按下事件发生在浏览器窗口外部,则不会发生此事件,因此可以通过以下方式将全局变量置于不一致状态:a)按下鼠标按钮,b)将鼠标移到浏览器窗口外部,c)释放鼠标按钮,d)将鼠标移回进入窗口-这不是解决方案
sereda 2010年

@sereda,您是对的。我在Firefox和Chrome上进行了测试,并且不会出现您描述的问题。现在,我在IE上进行了测试,发现了您描述的不良行为。你有什么建议?
塞巴斯蒂安·格里戈诺利

6

出于某些原因,绑定到mousemove事件时,如果将event.which属性设置为,1则单击左键或不按任何键。

我更改为mousedown活动,它可以正常工作:

  • 左:1
  • 中:2
  • 右:3

这是一个工作示例:http : //jsfiddle.net/marcosfromero/RrXbX/

jQuery代码是:

$('p').mousedown(function(event) {
    console.log(event.which);
    $('#button').text(event.which);
});

2

mousedown事件(以及其他事件)触发时,将更新这些变量;您会看到该事件保留的价值。请注意,它们是该事件的属性,而不是鼠标本身的属性

说明:对于按键或按钮事件,此属性指示所按下的特定按钮或按键。

没有“没有按钮按下”的值,因为该mousedown事件将永远不会触发以指示没有按钮按下。

你必须保持自己的全球[布尔]变量,其启用/关闭mousedown/ mouseup

  • 仅当按下按钮时浏览器窗口具有焦点时,这才起作用,这意味着在用户按下鼠标按钮和mousemove事件触发之间进行焦点切换将阻止其正常工作。但是,您实际上无能为力。

1

截至目前,以下功能适用于Firefox 47,Chrome 54和Safari 10。

$('#whichkey').bind('mousemove',function(e){
    if (e.buttons & 1 || (e.buttons === undefined && e.which == 1)) {
        $('#log').html('left button pressed');
    } else if (e.buttons & 2 || (e.buttons === undefined && e.which == 3)) {
        $('#log').html('right button pressed');
    } else {
        $('#log').html('no button pressed');
    }
});

0

对于寻求类似解决方案但不使用JQuery的用户,以下是解决问题的一种方法:

    canvas.addEventListener("mousemove", updatePosition_mouseNtouch);

    function updatePosition_mouseNtouch (evt) {
      // IF mouse is down THEN set button press flag
      if(evt.which === 1)
        leftButtonDown = true;
      // If you need to detect other buttons, then make this here
      // ... else if(evt.which === 2) middleButtonDown = true;
      // ... else if(evt.which === 3) rightButtonDown = true;
      // IF no mouse button is pressed THEN reset press flag(s)
      else
        leftButtonDown = false;

      if (leftButtonDown) {
        /* do some stuff */
      }
    }

我希望这对寻求答案的人有用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.