Detect middle button click (scroll button) with jQuery

Solution 1:

Well after a quick test it seems that the three are ordered as follows:

  • Left - 1
  • Middle - 2
  • Right - 3

So if you had:

$(document).mousedown(function(e){
    switch(e.which)
    {
        case 1:
            //left Click
        break;
        case 2:
            //middle Click
        break;
        case 3:
            //right Click
        break;
    }
    return true;// to allow the browser to know that we handled it.
});

Solution 2:

Please don't fire click actions during the mousedown event. It ignores the rest of the event pipeline and goes against current user expectations and design practices.

Problem

Here's a look at the normal order of events that fire for each click type:

$(document).on("mousedown mouseup click focus blur",function(e) {
  console.log("{" + e.which + ":" + e.type + "}"); 
});    

Click Events

Typically, we handle the very last click event because it signifies the users final intent to proceed with the current action.

The click event is fired when a pointing device button (usually a mouse's primary button) is pressed and released on a single element.

Unfortunately, middle mouse presses do not fire such an event (probably because doing so would force developers listening to the click event to distinguish between multiple possible invocations). But if we want to wire up actions against the middle click, we should follow the same UX expectations.

Solution

We'll listen for mousedown events and immediately attach a one time use handler for mouseup events. If the middle key was pressed and if the elements match, we'll trigger our own custom event with type middleclick, which we'll seed from the original event.

$(document).on("mousedown", function (e1) {
  $(document).one("mouseup", function (e2) {
    if (e1.which == 2 && e1.target == e2.target) {
      var e3 = $.event.fix(e2);
      e3.type = "middleclick";
      $(e2.target).trigger(e3)
    }
  });
});

That'll help separate out determining if the middle button was clicked with how we we want to handle it in that case, so we can setup a listener for our custom event type like this:

$(document).on("middleclick", function (e) {
    console.log("{" + e.target.nodeName.toLowerCase() + ":" + e.type + "}"); 
});

Working Demo in jsFiddle and Stack Snippets:

$(document).on("mousedown", function (e1) {
  $(document).one("mouseup", function (e2) {
    if (e1.which == 2 && e1.target == e2.target) {
    	var e3 = $.event.fix(e2);
      e3.type = "middleclick";
      $(e2.target).trigger(e3)
    }
  });
});

$(document).on("middleclick", function (e) {
  console.log("{" + e.target.nodeName.toLowerCase() + ":" + e.type + "}"); 
});

$(document).on("mousedown mouseup click focus blur",function(e) {
  console.log("{" + e.which + ":" + e.type + "}"); 
}); 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>

<div  style="background:#31965a;color:white;width:100px;height:100px;line-height:100px;text-align:center;">
  Click Me!
</div>

* Tested in Chrome, FF, Edge, & IE11

Solution 3:

Ok, I think I've got it. Here's a fiddle that seems to work. The trick (at least with FF4) seems to be to bind a click handler to the document and have it stop the propagation.

$(document).click(function(e){
        //not checking for the right click will prevent the context-menu from showing, you may or may not want to do that
        if (e.which != 3) { 
            e.preventDefault();
            return false;
        }
    });

This solution was found on this forum page.