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


574

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

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

这是由鼠标右键和鼠标左键触发的,能捕捉鼠标右键的方式是什么?如果以下内容存在,我将很高兴:

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

Answers:


900

从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!');
    }
});

4
@Jeff Hines-我试图在Chrome中检测到右键单击,此处显示的实现似乎可以正常工作,但是我意识到那仅仅是因为alert()阻止了上下文菜单的出现。:(嘘
jinglesthula 2011年

15
继续向下滚动,并确保阅读@JeffHines的答案。基本上,jQuery具有内置的事件'contextmenu'。
jpadvo 2011年

8
@jpadvo jQuery并未将其构建为“ contextmenu”,这contextmenu是浏览器的本机。在本机JavaScript中,您可以附加到oncontextmenu事件。
Naftali又名Neal

6
ie8:无法获取属性“哪个”的值:对象为null或未定义
Simon

2
是否可以在事件触发后阻止弹出上下文菜单?
kmoney12

251

编辑:我将其更改为适用于.on()在jQuery 1.7或更高版本中使用的动态添加的元素:

$(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>上的右键单击,这是对我
有用

17
右键单击不是触发上下文菜单的唯一方法。
Tim Down

3
我认为这是错误的方法,因为contextmenu事件触发并不总是意味着鼠标右键被单击。正确的方法是从鼠标事件中获取按钮信息(click在这种情况下)。
蒂姆·唐

1
嘿! 谢谢,这看起来不错,但我无法将其绑定到表行甚至正文等元素。它与$(window)一起使用。我正在使用bone.js来填充区域#main中的新内容,等等。–
哈里

84

通过检查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! */
    }
});

3
上面链接的jQuery插件正在使用e.button==2
ceejayoz

6
是的 与使用event.button跨浏览器的问题相比event.which,使用跨浏览器的问题更多,因为按钮使用的数字event.button有所不同。请看一下2009年1月的这篇文章-unixpapa.com/js/mouse.html
Russ Cam

1
mouseup验证一个人确实点击了该项目是否会更好?很多时候,如果我不小心单击某些东西,可以通过按住鼠标按钮并拖动到元素外部来防止单击。
克里斯·马里西克

1
@ChrisMarisic mouseup可能是一个更好的事件,这只是使用event.which鼠标单击的一个示例
Russ Cam

39

您还bind可以contextmenureturn 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/


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

$(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又名Neal,

1
@Raynos -有很多情况下,你的观点是无效的,如建立一个内部工具,或编码的东西你自己的个人use..I'm肯定还有更多
VSYNC

1
如果您实际上希望它像jQuery事件处理程序之一(例如click)那样工作,则应采用method.call(this, e);而不是method();That方法,method获取正确的值,this并正确地将事件对象传递给它。
杰里米·T

@JeremyT是真的...您可以通过任何您想要的方式处理回调^ _ ^
Naftali aka Neal 2012年

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。实际上消除了跨浏览器的不兼容性,但这就是我。
DwB


15

有很多非常好的答案,但是我只想在使用时谈一下IE9和IE <9之间的一个主要区别event.button

根据旧的Microsoft规范,event.button该代码不同于W3C使用的代码。W3C仅考虑3种情况:

  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标准甚至在理论上都不能支持这一点。


6
因此,一旦按下按钮,您将获得event.button === 0没有按钮被点击的出色的IEಠ_ಠ
Sinan

这是一个在IE的版本低于9
康斯坦丁Dinev

如果开发人员集体停止选择支持,即人们将不得不切换,那么开发人员将不再需要担心支持。
ahnbizcad 2015年

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事件”的答案


3

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...
  }
});

1

如果您正在寻找“更好的Javascript鼠标事件”,

  • 鼠标左键
  • 鼠标中键
  • 鼠标右键
  • 鼠标左键
  • 鼠标中键
  • 鼠标右键
  • 左击
  • 中间点击
  • 右键点击
  • 滚轮向上
  • 鼠标滚轮向下

看一下这个跨浏览器的普通javascript,它会触发上述事件,并消除令人头疼的工作。只需将其复制并粘贴到脚本的开头,或将其包含在脚本的<head>文档的文件中即可。然后绑定事件,请参考下面的下一个代码块,其中显示了一个捕获事件并触发分配给它们的函数的jquery示例,尽管这也适用于常规javascript绑定。

如果您有兴趣看到它起作用,请看一下jsFiddle:https ://jsfiddle.net/BNefn/

/**
   Better Javascript Mouse Events
   Author: Casey Childers
**/
(function(){
    // use addEvent cross-browser shim: https://gist.github.com/dciccale/5394590/
    var addEvent = function(a,b,c){try{a.addEventListener(b,c,!1)}catch(d){a.attachEvent('on'+b,c)}};

    /* This function detects what mouse button was used, left, right, middle, or middle scroll either direction */
    function GetMouseButton(e) {
        e = window.event || e; // Normalize event variable

        var button = '';
        if (e.type == 'mousedown' || e.type == 'click' || e.type == 'contextmenu' || e.type == 'mouseup') {
            if (e.which == null) {
                button = (e.button < 2) ? "left" : ((e.button == 4) ? "middle" : "right");
            } else {
                button = (e.which < 2) ? "left" : ((e.which == 2) ? "middle" : "right");
            }
        } else {
            var direction = e.detail ? e.detail * (-120) : e.wheelDelta;
            switch (direction) {
                case 120:
                case 240:
                case 360:
                    button = "up";
                break;
                case -120:
                case -240:
                case -360:
                    button = "down";
                break;
            }
        }

        var type = e.type
        if(e.type == 'contextmenu') {type = "click";}
        if(e.type == 'DOMMouseScroll') {type = "mousewheel";}

        switch(button) {
            case 'contextmenu':
            case 'left':
            case 'middle':
            case 'up':
            case 'down':
            case 'right':
                if (document.createEvent) {
                  event = new Event(type+':'+button);
                  e.target.dispatchEvent(event);
                } else {
                  event = document.createEventObject();
                  e.target.fireEvent('on'+type+':'+button, event);
                }
            break;
        }
    }

    addEvent(window, 'mousedown', GetMouseButton);
    addEvent(window, 'mouseup', GetMouseButton);
    addEvent(window, 'click', GetMouseButton);
    addEvent(window, 'contextmenu', GetMouseButton);

    /* One of FireFox's browser versions doesn't recognize mousewheel, we account for that in this line */
    var MouseWheelEvent = (/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel";
    addEvent(window, MouseWheelEvent, GetMouseButton);
})();

更好的鼠标单击事件示例(为简单起见,使用jquery,但以上内容可在跨浏览器上运行并触发相同的事件名称,IE在名称之前使用)

<div id="Test"></div>
<script type="text/javascript">
    $('#Test').on('mouseup',function(e){$(this).append(e.type+'<br />');})
              .on('mouseup:left',function(e){$(this).append(e.type+'<br />');})
              .on('mouseup:middle',function(e){$(this).append(e.type+'<br />');})
              .on('mouseup:right',function(e){$(this).append(e.type+'<br />');})

              .on('click',function(e){$(this).append(e.type+'<br />');})
              .on('click:left',function(e){$(this).append(e.type+'<br />');})
              .on('click:middle',function(e){$(this).append(e.type+'<br />');})
              .on('click:right',function(e){$(this).append(e.type+'<br />');})

              .on('mousedown',function(e){$(this).html('').append(e.type+'<br />');})
              .on('mousedown:left',function(e){$(this).append(e.type+'<br />');})
              .on('mousedown:middle',function(e){$(this).append(e.type+'<br />');})
              .on('mousedown:right',function(e){$(this).append(e.type+'<br />');})

              .on('mousewheel',function(e){$(this).append(e.type+'<br />');})
              .on('mousewheel:up',function(e){$(this).append(e.type+'<br />');})
              .on('mousewheel:down',function(e){$(this).append(e.type+'<br />');})
              ;
</script>

对于那些需要缩小版的人...

!function(){function e(e){e=window.event||e;var t="";if("mousedown"==e.type||"click"==e.type||"contextmenu"==e.type||"mouseup"==e.type)t=null==e.which?e.button<2?"left":4==e.button?"middle":"right":e.which<2?"left":2==e.which?"middle":"right";else{var n=e.detail?-120*e.detail:e.wheelDelta;switch(n){case 120:case 240:case 360:t="up";break;case-120:case-240:case-360:t="down"}}var c=e.type;switch("contextmenu"==e.type&&(c="click"),"DOMMouseScroll"==e.type&&(c="mousewheel"),t){case"contextmenu":case"left":case"middle":case"up":case"down":case"right":document.createEvent?(event=new Event(c+":"+t),e.target.dispatchEvent(event)):(event=document.createEventObject(),e.target.fireEvent("on"+c+":"+t,event))}}var t=function(e,t,n){try{e.addEventListener(t,n,!1)}catch(c){e.attachEvent("on"+t,n)}};t(window,"mousedown",e),t(window,"mouseup",e),t(window,"click",e),t(window,"contextmenu",e);var n=/Firefox/i.test(navigator.userAgent)?"DOMMouseScroll":"mousewheel";t(window,n,e)}();

1
$("body").on({
    click: function(){alert("left click");},
    contextmenu: function(){alert("right click");}   
});

您可能应该添加一些细节以了解其工作原理。-我同意,但是您没有向n00b解释原因。
亚当·科普利

0
$(document).ready(function () {
    var resizing = false;
    var frame = $("#frame");
    var origHeightFrame = frame.height();
    var origwidthFrame = frame.width();
    var origPosYGrip = $("#frame-grip").offset().top;
    var origPosXGrip = $("#frame-grip").offset().left;
    var gripHeight = $("#frame-grip").height();
    var gripWidth = $("#frame-grip").width();

    $("#frame-grip").mouseup(function (e) {
        resizing = false;
    });

    $("#frame-grip").mousedown(function (e) {
        resizing = true;
    });
    document.onmousemove = getMousepoints;
    var mousex = 0, mousey = 0, scrollTop = 0, scrollLeft = 0;
    function getMousepoints() {
        if (resizing) {
            var MouseBtnClick = event.which;
            if (MouseBtnClick == 1) {
                scrollTop = document.documentElement ? document.documentElement.scrollTop : document.body.scrollTop;
                scrollLeft = document.documentElement ? document.documentElement.scrollLeft : document.body.scrollLeft;
                mousex = event.clientX + scrollLeft;
                mousey = event.clientY + scrollTop;

                frame.height(mousey);
                frame.width(mousex);
            }
            else {
                resizing = false;
            }
        }
        return true;

    }


});

@ Nitin.Katti:-这是在鼠标点上进行的操作,如果冻结了鼠标的左键,则单击鼠标左键将停止调整大小。
user2335866 2013年

0

使用jquery,您可以使用 event object type

jQuery(".element").on("click contextmenu", function(e){
   if(e.type == "contextmenu") {
       alert("Right click");
   }
});

0

还有一种方法,不用JQuery就可以做到!

看看这个:

document.addEventListener("mousedown", function(evt) {
    switch(evt.buttons) {
      case 1: // left mouse
      case 2: // right mouse
      case 3: // middle mouse <- I didn't tested that, I just got a touchpad
    }
});

在我的电脑上(Ubuntu 14.04-FireFox),鼠标中键似乎为4。我相信左右两边是3,中间是4。必须有更好的“跨浏览器”,“跨平台”方式...
Paul

0
$.fn.rightclick = function(func){
    $(this).mousedown(function(event){
        if(event.button == 2) {
            var oncontextmenu = document.oncontextmenu;
            document.oncontextmenu = function(){return false;};
            setTimeout(function(){document.oncontextmenu = oncontextmenu;},300);
            func(event);
            return false;
        }
    });
};

$('.item').rightclick(function(e){ 
    alert("item");
}); 

0

对于那些想知道是否应该event.which香草JSAngular中使用的人:现在已弃用,因此更喜欢使用event.buttons代替。

注意 :使用此方法和(mousedown)事件:

  • 左键点击关联到1
  • 右键单击关联到2
  • 滚动按钮按下与4相关联

(mouseup)事件不会返回相同的数字,但 0

来源:https : //developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons


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

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

1
你好 该答案被标记为删除质量低下。看来您已经为前段时间回答的问题添加了答案。除非答案中有解释该贡献如何改善公认答案的解释,否则我也倾向于投票删除。
Popnoodles

1
@popnoodles,还可以,但请不要重复。
叶问咏春2014年
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.