35

I hate this mess with the mouse buttons created by W3C an MS! I want to know if the left mouse button is pressed when I get a mousedown event.

I use this code

// Return true if evt carries left mouse button press
function detectLeftButton(evt) {
  // W3C
  if (window.event == null) {
    return (evt.button == 0)
  }
  // IE
  else {
    return (evt.button == 1);
  }
}

However, it does not work in Opera and Chrome, because it so happens that window.event exists there too.

So what do I do? I have some browser detection, but we all know it cannot be relied upon with all the masking some browsers do lately. How do I detect the left mouse button RELIABLY?

jball
  • 24,791
  • 9
  • 70
  • 92
Boris Hamanov
  • 3,085
  • 9
  • 35
  • 58
  • I think the first two search results for `site:quirksmode.org left mouse button press` will help you. – N 1.1 Oct 15 '10 at 16:28
  • I read it, there is nothing there, only script for right mouse button – Boris Hamanov Oct 15 '10 at 16:34
  • You may want to look at how [jQuery](http://stackoverflow.com/questions/1206203/how-to-distinguish-left-mouse-click-and-right-with-jquery) solves the problem, or just use [jQuery's mousedown](http://api.jquery.com/mousedown/) and look at the `event.which` value. – jball Oct 15 '10 at 16:36
  • I don't have jQuery in my site and it seems $.browser.msie is yet another browser detection – Boris Hamanov Oct 15 '10 at 16:40
  • read the [highest rated non-accepted answer](http://stackoverflow.com/questions/1206203/how-to-distinguish-left-mouse-click-and-right-with-jquery/2725963#2725963) and you'll see how to do it with jQuery without using `$.browser.msi`. – jball Oct 15 '10 at 16:46

5 Answers5

49

Updated answer. The following will detect if the left and only the left mouse button is pressed:

function detectLeftButton(evt) {
    evt = evt || window.event;
    if ("buttons" in evt) {
        return evt.buttons == 1;
    }
    var button = evt.which || evt.button;
    return button == 1;
}

For much more information about handling mouse events in JavaScript, try http://unixpapa.com/js/mouse.html

Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • 3
    This does not work. Left button is 0 in all browsers except IE – Boris Hamanov Oct 15 '10 at 16:43
  • 6
    This does work. `which` returns 1 for the left button in all browsers except IE, where it will be undefined. In IE only, my `button` variable will therefore use the value for the event's `button` property instead of `which`, which is 1 for the left button. – Tim Down Oct 15 '10 at 16:46
  • Sorry, I did not pay attention to the which part. I tried it. It does work! Thanks Tim! – Boris Hamanov Oct 15 '10 at 17:03
  • 2
    While this does work - and I'd go as far as saying it is a very good solution - it still uses the non-standardised event.which property. So, ironically, you use a non-standardised property to distinguish the standards-compliant browsers from that other one. ;) – hallvors Oct 20 '10 at 01:45
  • 2
    @hallvors: Indeed. Unfortunately, identifying mouse buttons (along with identifying keypresses) is one area where standards and the reality of browser implementations are quite far apart. – Tim Down Oct 20 '10 at 08:17
  • Unfortunately, this answer won't work on Firefox because of [this bug - MouseEvent.Which always reports the same wrong value - 1](https://bugzilla.mozilla.org/show_bug.cgi?id=1048294). I'd suggest using @robocat approach instead. – raina77ow Apr 14 '16 at 16:20
  • 1
    @raina77ow I think you're right for `mouseover` events but the code is fine for `mousedown` events (https://jsbin.com/mupiri/), which is what the original question asked. I'll update the answer to check `buttons` when present. – Tim Down Apr 15 '16 at 10:27
  • You're right, for `mousedown` it works; somehow I missed that part in the question. ) In our case we implemented more generic function called for each type of mouse events. – raina77ow Apr 15 '16 at 10:31
14

There is now a W3C standard event.buttons property supported by IE9 in standards mode, and Gecko 15+.

The W3C completely stuffed up the event.button property, so for a standards compliant browser event.button is 0, but for browsers created before the standard, event.button is 1.

So code must avoid using event.button except for older browsers. The following code should work:

function detectLeftButton(event) {
    if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) {
        return false;
    } else if ('buttons' in event) {
        return event.buttons === 1;
    } else if ('which' in event) {
        return event.which === 1;
    } else {
        return (event.button == 1 || event.type == 'click');
    }
}
robocat
  • 5,293
  • 48
  • 65
  • 1
    +1. This looks like an improvement on my answer, although depending on requirements, you may want to do a bitwise comaprison with `buttons` (e.g. a value of 3 means left and right mouse buttons are pressed). This particular question seems to imply that the OP would want to know if the left button is pressed regardless of the status of any other button so the bitwise comparison would be appropriate. Example: `return (event.buttons & 1) === 1;` – Tim Down Nov 01 '12 at 14:48
  • 2
    @TimDown - I don't think a bitwise check is desired since the code is simpler without it. From usability, if the user has two buttons down, then presumably they mean something other than what left-click normally means. For the same reason in my own code I also check `!event.metaKey && !event.ctrlKey && !event.altKey && !event.shiftKey` to prevent capturing other clicks (shift-click is not the same as click). – robocat Dec 07 '12 at 00:59
0

You can use the following code-

onmouseup="if(window.event.which==1){//code for left click}
           else if(window.event.which==3){//code for right click}"
Rajesh Paul
  • 6,793
  • 6
  • 40
  • 57
0

Even though event.buttons now works in Chrome, Safari still does not support it. One workaround is to use onmousedown and onmouseup events at document or parent level like: onmousedown="bMouseDown=true" onmouseup="bMouseDown=false"

Igor Krupitsky
  • 787
  • 6
  • 9
-1
// 0 left, 2 right, 1 middle, other.. extra buttons, gaming mouses

var buttonsArray = [false, false, false, false, false, false, false, false, false];
var mousePressed = false;

document.onmousedown = function(e) {
    buttonsArray[e.button] = true;
    mousePressed = true;
};

document.onmouseup = function(e) {
    buttonsArray[e.button] = false;
    mousePressed = false;
};

document.oncontextmenu = function() {
    return false;
}

Explanation: When mouse is down, we change to true the pressed button in our buttons array. When mouse is up, we change to false the pressed button to false.

Now we can establish which button is pressed more accurately, but we have a right click problem.. because with that button we open a contextmenu at the browser, and that escapes our control... so, we disable the context menu in order to properly detect right click. If we don't do that, we must resolve left click too... and its a complication that escapes this response.

In order to simplify things, we can add another variable mousePressed and flag if mouse is down or up.

Works perfect on chrome, I didn't test it in other browser but I guess its ok in firefox and opera too... IE??? I don't care IE.

desertnaut
  • 57,590
  • 26
  • 140
  • 166
Lucas Tettamanti
  • 1,360
  • 8
  • 10