35

I am updating/debugging and expanding the capabilities of my draggable script and I need to be able to achieve the following result:

whatever.onRightMouseButtonMousedown = preventDefault();

I have done a lot of research to no avail, however, I know that it is possible to do this because when I use jquery-ui draggable, it prevents the ability to drag elements when you mousedown with the right mouse button. I want to mimic this ability, and learn how it works so that I can implement it now and in the future as needed.

Note: Please do not give me information about how to use jquery or jquery-ui draggable (I already am familiar with it), I want to learn how they implemented, or how it is possible to implement the detection of a mousedown with the right mouse button so that I can prevent elements from being draged with the right mouse button.

person0
  • 1,278
  • 2
  • 15
  • 20
  • This is not a duplicate. The question is specifically asking how to do it without using jQuery. – person0 Sep 03 '15 at 16:49

4 Answers4

43

Normally when you have any kind of mouse event, you'll want to have it only operate on one type of mouse click. Therefore, the events passed to your callbacks have a property which allow you to distinguish between types of clicks.

This data is passed back through the button property of the event data. See MDN for finding out what values represent what data.

Therefore, you don't disable the right click, you instead only enable your functionality for the left click. Here's a [poor] example:

element.onmousedown = function(eventData) {
  if (eventData.button === 0) {
      alert("From JS: the (left?) button is down!")
  }
}  

the equivalent in jQuery is:

$("div").mousedown(function(eventData) {
    if (eventData.which === 0) {
        alert("From JQuery: which=" + eventData.which)
    }
});

Note that if you don't use jquery, the values returned will be different across browsers. jQuery unifies the values across browsers, using 1 for left, 2 for middle, 3 for right:

 element.onmousedown = function(eventData) {
   if (eventData.button === 0) {
     console.log("From JS: the (left?) button is down!")
   }
 }

 $("#element").ready(function() {
   $("div").mousedown(function(de) {
     console.log("From JQuery: which=" + de.which);
   });
 });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="element" style="width: 100px; height: 100px; background-color: blue" />
auipga
  • 300
  • 3
  • 10
zastrowm
  • 8,017
  • 3
  • 43
  • 63
  • 2
    Thank you, I actually already figured this out before coming back to check your comment, I would simply add that to make it work across browsers (at least modern browsers anyway) you just need to check for `event.which` and `event.button`, this is how I ended up resolving it: `if (evt.which === 3 || evt.button === 2) {evt.preventDefault();` – person0 Mar 01 '12 at 19:33
  • 5
    FYI, for the left mouse button `event.button === 0`, for the mousewheel `event.button === 1`, and for the right mouse button `event.button === 2` as explained at https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button#Return_value – F Lekschas Dec 12 '18 at 16:19
11

The HTML, Javascript and demo:

function mouseDown(e) {
  e = e || window.event;
  switch (e.which) {
    case 1: alert('left'); break;
    case 2: alert('middle'); break;
    case 3: alert('right'); break; 
  }
}
<a href="#" onmousedown="mouseDown(event);">aaa</a>
Donald Duck
  • 8,409
  • 22
  • 75
  • 99
atiruz
  • 2,782
  • 27
  • 36
3

It's not very simple. Quirksmode.org has an article about event properties.

Look under 'Which mouse button has been clicked?' / 'Right click'. It varies by browser.

andrewmu
  • 14,276
  • 4
  • 39
  • 37
  • 10
    I know this is from a while ago, but I clicked that link and saw the line "Not even explorer 6 supports it yet" meaning this article is ANCIENT. – J S Dec 08 '13 at 20:11
0

It is also possible to have several mouse buttons pressed at the same time.

To know which mouse buttons are pressed,
you have to use Boolean algebra operators !

proceed as follows:

const
  divX   = document.querySelector('#divX')
, Buttons_status = 
    { left       : { key : 0b00001, isDown: false }  // Primary button   (usually the left button)
    , right      : { key : 0b00010, isDown: false }  // Secondary button (usually the right button)
    , center     : { key : 0b00100, isDown: false }  // Auxiliary button (usually the mouse wheel button or middle button) 
    , bt_Back    : { key : 0b01000, isDown: false }  // 4th button (typically the "Browser Back" button)
    , bt_Forward : { key : 0b10000, isDown: false }  // 5th button (typically the "Browser Forward" button) 
    }

function testingButtons(e)
  {
  let DownBtns = ''
  for (let bt in Buttons_status )
    {
    Buttons_status[bt].isDown = !!(Buttons_status[bt].key & e.buttons )

    if (Buttons_status[bt].isDown) DownBtns += ' ' + bt
    }
  console.log ('Down buttton(s) :', DownBtns ? DownBtns : 'none' ) 
  // console.log( Buttons_status )
  }
 
divX.onmousedown = testingButtons
divX.onmouseup   = testingButtons

document.body.oncontextmenu =_=> false  // for clear testing
#divX {
  display    : inline-block;
  background : lawngreen;
  margin     : .7em;
  padding    : 1em .7em;
  }
button {
  display        : inline-block;
  vertical-align : top;
  }
.as-console-wrapper {
  max-height: 1.6em !important; 
  }
<div id="divX"> 
  Do a mouse click anywhere here.
  <br><br>
  You can activate several buttons
  <br>
  <small>[do not release the previous button(s) when you press a new one]</small>
  <br><br>
  <small>(then realease just one of them)</small>
</div>

<button onclick="console.clear()">Clear</button>
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40