如何使用jQuery区分鼠标左键和右键点击

619

如何使用jQuery获取鼠标点击的按钮?

$('div').bind('click', function(){
    alert('clicked');
});

这是通过右键和左键触发的,有什么方法可以捕捉到右键单击吗?如果下面的类似方法存在,我会很高兴:

$('div').bind('rightclick', function(){ 
    alert('right mouse button is pressed');
});

大家都应该看一下我在这里的答案!(链接) - Mister Jojo
20个回答

950
自 jQuery 版本 1.1.3 开始,event.which 标准化了 event.keyCodeevent.charCode,因此您无需担心浏览器兼容性问题。有关 event.which 的文档 event.which 将分别为左键、中键和右键返回 1、2 或 3:
$('#element').mousedown(function(event) {
    switch (event.which) {
        case 1:
            alert('Left Mouse button pressed.');
            break;
        case 2:
            alert('Middle Mouse button pressed.');
            break;
        case 3:
            alert('Right Mouse button pressed.');
            break;
        default:
            alert('You have a strange Mouse!');
    }
});

5
@Jeff Hines - 我试图在Chrome中检测右键单击事件,这里展示的实现似乎运行良好,但我意识到那只是因为alert()阻止了上下文菜单出现。 :( 噫 - jinglesthula
17
请继续向下滚动并确保阅读@JeffHines的答案。基本上,jQuery内置了事件“contextmenu”,可用于区分左右鼠标点击。 - jpadvo
9
jQuery没有将其构建为"contextmenu",contextmenu是浏览器本身的功能。在原生JavaScript中,您可以附加到oncontextmenu事件。 - Naftali
6
IE8:无法获取属性“which”的值:对象为 null 或未定义。 - Simon
2
在事件被触发后,我能否防止上下文菜单弹出? - kmoney12
显示剩余9条评论

262

编辑: 我修改了代码,使其能够处理使用jQuery 1.7或更高版本的.on()动态添加的元素:

$(document).on("contextmenu", ".element", function(e){
   alert('Context Menu event has fired!');
   return false;
});

演示:jsfiddle.net/Kn9s7/5

[原始帖子开始] 这是对我有用的方法:

$('.element').bind("contextmenu",function(e){
   alert('Context Menu event has fired!');
   return false;
}); 

如果你想要多种解决方案^^

编辑: Tim Down 提出了一个很好的观点,即不一定会通过right-click来触发contextmenu事件,还有可能是按下上下文菜单键(这可以看作是替代right-click)


28
这应该是被采纳的答案。这个事件在所有相关的浏览器上运行,并触发整个点击过程(鼠标按下 + 靠近时鼠标松开)。 - Nick Retallack
3
这是我在捕获<textarea>右键单击方面使用的唯一有效解决方案。 - Tyler
17
右键单击并不是触发上下文菜单的唯一方式。 - Tim Down
3
我认为这种方法不正确,因为 contextmenu 事件的触发并不总是意味着右键被点击。正确的方法是从鼠标事件(在这种情况下是 click)中获取按钮信息。 - Tim Down
1
嗨!谢谢,这看起来很棒,但我无法将其绑定到像表格行甚至正文之类的元素上。它可以与$(window)一起使用。我正在使用backbone.js来填充一个名为#main的区域以及新内容等。 - Harry
显示剩余3条评论

86

通过检查鼠标事件对象的which属性,您可以轻松确定按下了哪个鼠标按钮:

/*
  1 = Left   mouse button
  2 = Centre mouse button
  3 = Right  mouse button
*/

$([selector]).mousedown(function(e) {
    if (e.which === 3) {
        /* Right mouse button was clicked! */
    }
});

4
上面链接的 jQuery 插件使用了 e.button==2 - ceejayoz
6
使用event.which比使用event.button更容易跨浏览器兼容,因为在event.button中用于表示按钮的数字是不同的。请参考这篇2009年1月的文章 - http://unixpapa.com/js/mouse.html - Russ Cam
1
这样做是否更好,将mouseup用于验证用户是否真正点击了该项?有很多情况下,如果我不小心点击了某个元素,我可以通过按住鼠标按钮并将其拖到元素外部来防止点击。 - Chris Marisic
1
@ChrisMarisic mouseup可能是更好的事件,这只是使用event.which处理鼠标按钮点击的示例。 - Russ Cam

39

您还可以绑定contextmenu返回false

$('selector').bind('contextmenu', function(e){
    e.preventDefault();
    //code
    return false;
});

演示:http://jsfiddle.net/maniator/WS9S2/

或者您可以制作一个快速插件来实现同样的功能:

(function( $ ) {
  $.fn.rightClick = function(method) {

    $(this).bind('contextmenu rightclick', function(e){
        e.preventDefault();
        method();
        return false;
    });

  };
})( jQuery );

演示:http://jsfiddle.net/maniator/WS9S2/2/


使用 jQuery >= 1.7的 .on(...)

$(document).on("contextmenu", "selector", function(e){
    e.preventDefault();
    //code
    return false;
});  //does not have to use `document`, it could be any container element.

示例:http://jsfiddle.net/maniator/WS9S2/283/


1
@Raynos 是的,但这是处理右键单击事件的唯一方法。如果上下文菜单仍然存在,则无法在右键单击时执行任何操作。 - Naftali
1
@Raynos - 有很多情况下您的观点是无效的,比如构建一个内部工具,或者编写一些供个人使用的代码..我相信还有更多例子。 - vsync
1
如果你真的希望它像 jQuery 事件处理程序之一(例如 click)那样运行,那么应该使用 method.call(this, e); 而不是 method(); 这样,method 就可以正确地获取 this 的值,并且也可以正确地传递事件对象。 - Jeremy T
@JeremyT 那是真的... 你可以以任何你想要的方式处理回调 ^_^ - Naftali

30

$("#element").live('click', function(e) {
  if( (!$.browser.msie && e.button == 0) || ($.browser.msie && e.button == 1) ) {
       alert("Left Button");
    }
    else if(e.button == 2){
       alert("Right Button");
    }
});

关于目前事情的更新:

var $log = $("div.log");
$("div.target").on("mousedown", function() {
  $log.text("Which: " + event.which);
  if (event.which === 1) {
    $(this).removeClass("right middle").addClass("left");
  } else if (event.which === 2) {
    $(this).removeClass("left right").addClass("middle");
  } else if (event.which === 3) {
    $(this).removeClass("left middle").addClass("right");
  }
});
div.target {
  border: 1px solid blue;
  height: 100px;
  width: 100px;
}

div.target.left {
  background-color: #0faf3d;
}

div.target.right {
  background-color: #f093df;
}

div.target.middle {
  background-color: #00afd3;
}

div.log {
  text-align: left;
  color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="target"></div>
<div class="log"></div>


1
这是否只适用于MSIE?它能够在其他浏览器中使用吗? - Taryn East
13
由于 event.which 已经被引入,消除了跨浏览器兼容性问题,因此该方法现在已不再必要。 - Acorn
8
我怀疑 event.which 实际上消除了跨浏览器的不兼容性,但这只是我的看法。 - DwB

18
$.event.special.rightclick = {
    bindType: "contextmenu",
    delegateType: "contextmenu"
};

$(document).on("rightclick", "div", function() {
    console.log("hello");
    return false;
});

http://jsfiddle.net/SRX3y/8/


17

有很多非常好的答案,但我想强调IE9和IE< 9在使用event.button时的一个主要区别。

根据旧版Microsoft规范中event.button的代码与W3C使用的代码不同。W3C只考虑了三种情况:

  1. 左键点击 - event.button === 1
  2. 右键点击 - event.button === 3
  3. 中键点击 - event.button === 2

然而在早期的Internet Explorer版本中,Microsoft针对按下的按钮反转了位,共有8个选项:

  1. 没有点击任何按钮 - event.button === 0或000
  2. 左键被单击 - event.button === 1或001
  3. 右键被单击 - event.button === 2或010
  4. 左右键都被单击 - event.button === 3或011
  5. 中键被单击 - event.button === 4或100
  6. 中键和左键都被单击 - event.button === 5或101
  7. 中键和右键都被单击 - event.button === 6或110
  8. 所有3个按钮都被单击 - event.button === 7或111

尽管这理论上是应该的,但没有任何一个Internet Explorer版本支持同时按下两个或三个按钮的情况。我提到这一点是因为W3C标准甚至在理论上也无法支持此操作。


7
按下按钮后,你会得到 event.button === 0 的结果,表示没有按钮被点击。这在IE浏览器中表现得相当出色 ಠ_ಠ - Sinan
这是在低于9版本的IE中。 - Konstantin Dinev
1
如果开发人员集体选择不再支持IE,那么用户将不得不转换浏览器,然后开发人员就不必再担心支持IE了。 - ahnbizcad
1
如果您想追踪多个按钮同时被按下的情况,请使用event.buttons。它还处理鼠标按钮4和5(在浏览器中前进/后退)。请参阅:https://jsfiddle.net/9hponw1t/1 - mbomb007

8
我认为稍微调整TheVillageIdiot的回答会更加简洁:
$('#element').bind('click', function(e) {
  if (e.button == 2) {
    alert("Right click");
  }
  else {
    alert("Some other click");
  }
}

编辑:JQuery提供了一个e.which属性,分别返回1、2、3表示左键、中键和右键单击。因此,您也可以使用if (e.which == 3) { alert("right click"); }

另请参阅:"使用中键触发onclick事件"的答案。


4
对于那些想知道是否应该在原生JS或Angular中使用event.which的人:它现在已经被弃用,因此最好使用event.buttons代替。
注意:使用此方法和(mousedown)事件:
- 左键单击关联到1 - 右键单击关联到2 - 滚动按钮按下关联到4
(mouseup)事件将不会返回相同的数字,而是0。
来源:https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons

它还处理鼠标按钮4和5(在浏览器中前进/后退)。请参见:https://jsfiddle.net/9hponw1t/1 - mbomb007

4

event.which === 1 确保这是一个左键单击(使用jQuery时)。

但是您还应该考虑修改键:ctrlcmdshiftalt

如果您只想捕获简单的、未修改的左键单击,可以像这样做:

var isSimpleClick = function (event) {
  return !(
    event.which !== 1 || // not a left click
    event.metaKey ||     // "open link in new tab" (mac)
    event.ctrlKey ||     // "open link in new tab" (windows/linux)
    event.shiftKey ||    // "open link in new window"
    event.altKey         // "save link as"
  );
};

$('a').on('click', function (event) {
  if (isSimpleClick(event)) {
    event.preventDefault();
    // do something...
  }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接