Comment faire la distinction entre le clic gauche et le clic droit de la souris avec jQuery

574

Comment obtenir le bouton de la souris cliqué en utilisant jQuery?

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

cela est déclenché par un clic droit et gauche, quelle est la façon de pouvoir attraper le clic droit de la souris? Je serais heureux si quelque chose comme ci-dessous existe:

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

Réponses:

900

À partir de jQuery version 1.1.3, event.whichnormalise event.keyCodeet event.charCodevous n'avez donc pas à vous soucier des problèmes de compatibilité du navigateur. Documentation surevent.which

event.which donnera respectivement 1, 2 ou 3 pour les boutons gauche, central et droit de la souris:

$('#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!');
    }
});
Gland
la source
4
@Jeff Hines - J'essayais de détecter un clic droit dans Chrome et l'implémentation présentée ici semblait bien fonctionner, mais je me suis rendu compte que c'était uniquement parce que l'alerte () empêchait le menu contextuel d'apparaître. :( boo
jinglesthula
15
Continuez à faire défiler vers le bas et assurez-vous de lire la réponse de @ JeffHines . Fondamentalement, jQuery a ce intégré comme événement 'menu contextuel'.
jpadvo
8
@jpadvo jQuery ne l'a pas construit comme "contextmenu", contextmenuest natif du navigateur. en JavaScript natif, vous pouvez joindre à l' oncontextmenuévénement.
Naftali aka Neal
6
ie8: Impossible d'obtenir la valeur de la propriété 'which': l'objet est nul ou non défini
Simon
2
Puis-je empêcher le menu contextuel de s'afficher après le déclenchement de l'événement?
kmoney12
251

Edit : je l'ai changé pour fonctionner pour les éléments ajoutés dynamiquement en utilisant .on()dans jQuery 1.7 ou supérieur:

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

Démo: jsfiddle.net/Kn9s7/5

[Début du message original] C'est ce qui a fonctionné pour moi:

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

Dans le cas où vous êtes dans plusieurs solutions ^^

Edit : Tim Down soulève un bon point que ce ne sera pas toujours un right-clickqui déclenche l' contextmenuévénement, mais aussi lorsque la touche de menu contextuel est enfoncée (ce qui est sans doute un remplacement pour a right-click)

Jeff Hines
la source
28
Ce devrait être la réponse acceptée. Cet événement fonctionne dans tous les navigateurs pertinents et se déclenche sur un clic entier (souris vers le bas + souris vers le haut à proximité).
Nick Retallack
3
C'est la seule solution qui a fonctionné pour moi en ce qui concerne la capture du clic droit sur une <textarea>
styler1972
17
Un clic droit n'est cependant pas le seul moyen de déclencher le menu contextuel.
Tim Down
3
Je pense que c'est la mauvaise approche car le contextmenudéclenchement de l' événement n'implique pas toujours que le bouton droit de la souris a été cliqué. L'approche correcte consiste à obtenir des informations sur les boutons à partir d'un événement de souris ( clickdans ce cas).
Tim Down
1
Hey! Merci, cela a l'air génial, mais je ne peux pas le faire se lier à un élément comme une ligne de tableau ou même le corps. cela fonctionne avec $ (fenêtre). J'utilise backbone.js pour remplir une zone #main avec du nouveau contenu, etc.
Harry
84

Vous pouvez facilement savoir quel bouton de la souris a été enfoncé en vérifiant la whichpropriété de l'objet événement sur les événements de la souris:

/*
  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! */
    }
});
Russ Cam
la source
3
Le plugin jQuery lié ci-dessus utilise à la e.button==2place.
ceejayoz
6
oui. L'utilisation de plusieurs event.buttonnavigateurs est plus problématique que event.whichles nombres utilisés pour les boutons event.buttonvarient. Jetez un oeil à cet article de janvier 2009 - unixpapa.com/js/mouse.html
Russ Cam
1
Ne serait-il pas préférable de mouseupvérifier qu'une personne a vraiment cliqué sur l'élément? Il y a beaucoup de fois si je clique accidentellement sur quelque chose, je peux empêcher le clic en maintenant le bouton de la souris enfoncé et en faisant glisser l'extérieur de l'élément.
Chris Marisic
1
@ChrisMarisic mouseupest probablement un meilleur événement, ce n'est qu'un exemple de l'utilisation des event.whichclics de souris
Russ Cam
39

Vous pouvez aussi bindà contextmenuet return false:

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

Démo: http://jsfiddle.net/maniator/WS9S2/

Ou vous pouvez créer un plugin rapide qui fait de même:

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

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

  };
})( jQuery );

Démo: http://jsfiddle.net/maniator/WS9S2/2/


En utilisant .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.

Démo: http://jsfiddle.net/maniator/WS9S2/283/

Naftali aka Neal
la source
1
@Raynos oui, mais c'est la seule façon de gérer un événement de clic droit. si le menu contextuel était toujours là, vous ne pouviez rien faire avec un clic droit.
Naftali aka Neal
1
@Raynos - il y a de nombreux cas où votre argument n'est pas valide, comme la construction d'un outil interne ou le codage de quelque chose pour votre usage personnel .. Je suis sûr qu'il y en a plus
vsync
1
Si vous vouliez réellement qu'il agisse comme l'un des gestionnaires d'événements jQuery (comme click, par exemple), cela devrait être à la method.call(this, e);place de method();That way, methodobtient la valeur correcte pour thiset a également l'objet d'événement qui lui est transmis correctement.
Jeremy T
@JeremyT c'est vrai ... vous pouvez gérer le rappel comme vous le souhaitez ^ _ ^
Naftali aka Neal
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");
    }
});

Mise à jour de l'état actuel des choses:

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>

TheVillageIdiot
la source
1
est-ce spécifique à msie? c'est à dire est-il portable sur d'autres navigateurs?
Taryn East
13
Cette méthode est désormais inutile car elle event.whicha été introduite, ce qui élimine la compatibilité entre navigateurs.
Acorn
8
Je soupçonne un événement qui élimine réellement l'incompatibilité entre navigateurs, mais ce n'est que moi.
DwB
18
$.event.special.rightclick = {
    bindType: "contextmenu",
    delegateType: "contextmenu"
};

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

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

Esailija
la source
15

Il y a beaucoup de très bonnes réponses, mais je veux juste aborder une différence majeure entre IE9 et IE <9 lors de l'utilisation event.button.

Selon l'ancienne spécification Microsoft, event.buttonles codes diffèrent de ceux utilisés par le W3C. Le W3C ne considère que 3 cas:

  1. Le bouton gauche de la souris est cliqué - event.button === 1
  2. Le bouton droit de la souris est cliqué - event.button === 3
  3. Le bouton central de la souris est cliqué - event.button === 2

Dans les explorateurs Internet plus anciens, cependant, Microsoft retourne un peu le bouton enfoncé et il y a 8 cas:

  1. Aucun bouton n'est cliqué - event.button === 0ou 000
  2. Le bouton gauche est cliqué - event.button === 1ou 001
  3. Le bouton droit est cliqué - event.button === 2ou 010
  4. Les boutons gauche et droit sont cliqués - event.button === 3ou 011
  5. Le bouton du milieu est cliqué - event.button === 4ou 100
  6. Les boutons du milieu et de gauche sont cliqués - event.button === 5ou 101
  7. Les boutons du milieu et de droite sont cliqués - event.button === 6ou 110
  8. Les 3 boutons sont cliqués - event.button === 7ou 111

Malgré le fait que c'est théoriquement la façon dont cela devrait fonctionner, aucun Internet Explorer n'a jamais pris en charge les cas de deux ou trois boutons enfoncés simultanément. Je le mentionne parce que la norme W3C ne peut même pas théoriquement supporter cela.

Konstantin Dinev
la source
6
donc sur le bouton pressé vous obtenez event.button === 0ce qui n'est pas un bouton cliqué, brillant IEಠ_ಠ
Sinan
C'est dans les versions d'IE inférieures à 9.
Konstantin Dinev
Si collectivement les développeurs arrêtaient de choisir de prendre en charge ie, les gens devraient changer, et alors les développeurs n'auraient plus à se soucier de supporter ie.
ahnbizcad
8

Il me semble qu'une légère adaptation de la réponse de TheVillageIdiot serait plus nette:

$('#element').bind('click', function(e) {
  if (e.button == 2) {
    alert("Right click");
  }
  else {
    alert("Some other click");
  }
}

EDIT: JQuery fournit un e.whichattribut, renvoyant 1, 2, 3 pour le clic gauche, central et droit respectivement. Vous pouvez donc également utiliserif (e.which == 3) { alert("right click"); }

Voir aussi: réponses à "Déclenchement d'un événement onclick en utilisant le clic du milieu"

Dan Burton
la source
3

event.which === 1 s'assure qu'il s'agit d'un clic gauche (lors de l'utilisation de jQuery).

Mais vous devriez également penser aux touches de modification: ctrlcmdshiftalt

Si vous souhaitez uniquement capturer des clics gauche simples et non modifiés, vous pouvez faire quelque chose comme ceci:

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...
  }
});
callum
la source
1

Si vous recherchez des "meilleurs événements de souris Javascript" qui permettent

  • mousedown gauche
  • mousedown moyen
  • droit de la souris
  • souris gauche
  • souris moyenne
  • bonne souris
  • click gauche
  • Clic du milieu
  • clic-droit
  • roue de souris vers le haut
  • molette vers le bas

Jetez un oeil à ce javascript normal croisé qui déclenche les événements ci-dessus et supprime le mal de tête. Copiez-le et collez-le simplement dans la tête de votre script, ou incluez-le dans un fichier <head>de votre document. Liez ensuite vos événements, reportez-vous au bloc de code suivant ci-dessous qui montre un exemple jquery de capture des événements et de déclenchement des fonctions qui leur sont attribuées, bien que cela fonctionne également avec la liaison javascript normale.

Si vous êtes intéressé à le voir fonctionner, jetez un œil au 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);
})();

Meilleur exemple d'événements de clic de souris (utilise jquery pour plus de simplicité, mais ce qui précède fonctionnera dans plusieurs navigateurs et déclenchera les mêmes noms d'événements, qu'IE utilise avant les noms)

<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>

Et pour ceux qui ont besoin de la version minifiée ...

!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)}();
NinjaKC
la source
1
$("body").on({
    click: function(){alert("left click");},
    contextmenu: function(){alert("right click");}   
});
AK
la source
Vous devriez probablement ajouter quelques détails sur pourquoi cela fonctionne. - Je suis d'accord, mais vous n'expliquez pas à un n00b pourquoi.
Adam Copley
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;

    }


});
user2335866
la source
@ Nitin.Katti: - Ceci fonctionne sur le point de la souris et sur le bouton gauche si vous gelez le bouton gauche de la souris puis arrêtez le redimensionnement.
user2335866
0

Avec jquery, vous pouvez utiliser event object type

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

il y a aussi un moyen de le faire sans JQuery!

Regarde ça:

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

la source
La souris du milieu semblait 4 sur mon PC (Ubuntu 14.04 - FireFox). Je crois que gauche et droite ensemble est 3 et le milieu est 4 .. Il doit y avoir une meilleure façon de "cross browser", "cross platform" ...
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");
}); 
user3361174
la source
0

Pour ceux qui se demandent s'ils devraient ou non utiliser event.whichdans vanilla JS ou Angular : Il est maintenant obsolète, alors préférez utiliser à la event.buttonsplace.

Remarque: Avec cette méthode et l' événement (mousedown) :

  • clic gauche appuyez sur est associé à 1
  • clic droit appuyez sur est associé à 2
  • appuyez sur le bouton de défilement est associé à 4

et (mouseup) l' événement ne renverra PAS les mêmes chiffres mais 0 place.

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

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

   $(document).on("rightclick", "div", function() {
   console.log("hello");
    return false;
    });
Yip Man WingChun
la source
1
Salut. Cette réponse est signalée comme de faible qualité pour la suppression. Il semble que vous ayez ajouté une réponse à une question à laquelle il a été répondu il y a quelque temps. À moins qu'il n'y ait une explication dans la réponse qui explique comment cette contribution améliore la réponse acceptée, je suis enclin à voter pour la supprimer également.
Popnoodles
1
@popnoodles, ça va mais ne le répétez jamais.
Yip Man WingChun