Come distinguere tra clic sinistro e destro del mouse con jQuery


574

Come si ottiene il pulsante del mouse cliccato usando jQuery?

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

questo è innescato dal clic destro e sinistro, qual è il modo di essere in grado di catturare il clic destro del mouse? Sarei felice se esistesse qualcosa come sotto:

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

Risposte:


900

A partire dalla versione 1.1.3 di jQuery, si event.whichnormalizza event.keyCodee event.charCodequindi non devi preoccuparti di problemi di compatibilità del browser. Documentazione suevent.which

event.which fornirà 1, 2 o 3 rispettivamente per i pulsanti sinistro, medio e destro del mouse, quindi:

$('#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 - Stavo cercando di rilevare un clic destro in Chrome e l'implementazione mostrata qui sembrava funzionare correttamente, ma mi sono reso conto che era solo perché l'avviso () ha impedito la visualizzazione del menu di scelta rapida. :( boo
jinglesthula,

15
Continua a scorrere verso il basso e assicurati di leggere la risposta di @ JeffHines . Fondamentalmente, jQuery ha questo incorporato come "contesto menu" dell'evento.
jpadvo,

8
@jpadvo jQuery non lo ha creato come "contextmenu", contextmenuè nativo del browser. in JavaScript nativo è possibile allegare oncontextmenuall'evento.
Naftali aka Neal,

6
ie8: Impossibile ottenere il valore della proprietà 'quale': l'oggetto è nullo o non definito
Simon

2
Posso impedire che il menu di scelta rapida venga visualizzato dopo che l'evento è stato attivato?
kmoney12

251

Modifica : l'ho modificato per funzionare con elementi aggiunti dinamicamente usando .on()in jQuery 1.7 o versioni successive:

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

Demo: jsfiddle.net/Kn9s7/5

[Inizio del post originale] Questo è ciò che ha funzionato per me:

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

Nel caso in cui ti piaccia più soluzioni ^^

Modifica : Tim Down fa apparire bene che non sarà sempre un evento right-clickche genera l' contextmenuevento, ma anche quando viene premuto il tasto del menu contestuale (che è probabilmente un sostituto di un right-click)


28
Questa dovrebbe essere la risposta accettata. Questo evento funziona in tutti i browser e inneschi pertinenti su un intero clic (mouse in giù + mouse in su in prossimità).
Nick Retallack,

3
Questa è l' unica soluzione che ha funzionato per me per quanto riguarda l'acquisizione del clic destro su una <textarea>
styler1972,

17
Fare clic con il tasto destro non è l'unico modo per attivare il menu di scelta rapida.
Tim Down

3
Penso che sia l'approccio sbagliato perché l' contextmenuattivazione dell'evento non implica sempre che sia stato cliccato il pulsante destro del mouse. L'approccio corretto è ottenere informazioni sui pulsanti da un evento del mouse ( clickin questo caso).
Tim Down,

1
Hey! Grazie, sembra fantastico, ma non riesco a legarlo a un elemento come una riga del tavolo o persino il corpo. funziona con $ (finestra). Sto usando backbone.js per popolare un'area #main con nuovi contenuti ecc.
Harry

84

Puoi facilmente sapere quale pulsante del mouse è stato premuto controllando la whichproprietà dell'oggetto evento sugli eventi del mouse:

/*
  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
Al suo e.button==2posto utilizza invece il plug-in jQuery collegato sopra .
Ceejayoz,

6
Sì. L'uso del event.buttonbrowser incrociato è più un problema rispetto event.whichal event.buttonvariare dei numeri utilizzati per i pulsanti . Dai un'occhiata a questo articolo di gennaio 2009 - unixpapa.com/js/mouse.html
Russ Cam

1
Non sarebbe meglio mouseupverificare che una persona abbia effettivamente cliccato sull'elemento? Ci sono molte volte se faccio accidentalmente clic su qualcosa che sono in grado di impedire il clic tenendo premuto il pulsante del mouse e trascinando all'esterno dell'elemento.
Chris Marisic,

1
@ChrisMarisic mouseupè probabilmente un evento migliore, questo è solo un esempio dell'uso dei event.whichclic del pulsante del mouse
Russ Cam

39

È possibile anche bindper contextmenue return false:

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

Demo: http://jsfiddle.net/maniator/WS9S2/

Oppure puoi creare un plugin rapido che faccia lo stesso:

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

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

  };
})( jQuery );

Demo: http://jsfiddle.net/maniator/WS9S2/2/


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

Demo: http://jsfiddle.net/maniator/WS9S2/283/


1
@Raynos sì, ma questo è l'unico modo per gestire un evento con il tasto destro. se il menu di scelta rapida fosse ancora presente, non è possibile eseguire alcuna operazione con un clic destro.
Naftali aka Neal,

1
@Raynos - ci sono molti casi in cui il tuo punto non è valido, come la costruzione di uno strumento interno o la codifica di qualcosa per il tuo uso personale ... Sono sicuro che ce ne sono altri
vsync,

1
Se in realtà volevi che si comportasse come uno dei gestori di eventi jQuery (come clic, ad esempio), che dovrebbe essere method.call(this, e);invece in method();quel modo, methodottiene il valore corretto per thise anche l'oggetto evento gli è passato correttamente.
Jeremy T

@JeremyT è vero ... potresti gestire la richiamata come vuoi ^ _ ^
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");
    }
});

Aggiornamento per lo stato attuale delle cose:

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
è specifico per msie? cioè è portatile su altri browser?
Taryn East

13
Questo metodo non è più necessario poiché event.whichè stato introdotto per eliminare la compatibilità tra browser.
Ghianda

8
Ho il sospetto di un evento che elimina effettivamente l'incompatibilità tra browser, ma sono solo io.
DW

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

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

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


15

Ci sono molte risposte molto buone, ma voglio solo toccare una delle principali differenze tra IE9 e IE <9 durante l'utilizzo event.button.

Secondo le vecchie specifiche Microsoft per event.buttoni codici differiscono da quelli utilizzati dal W3C. Il W3C considera solo 3 casi:

  1. Si fa clic sul pulsante sinistro del mouse - event.button === 1
  2. Si fa clic con il pulsante destro del mouse - event.button === 3
  3. Si fa clic sul pulsante centrale del mouse - event.button === 2

Nei vecchi Internet Explorer, tuttavia, Microsoft sta lanciando un po 'il pulsante premuto e ci sono 8 casi:

  1. Nessun pulsante è stato cliccato - event.button === 0 o su 000
  2. Fare clic sul pulsante sinistro - event.button === 1 o 001
  3. Fare clic sul pulsante destro - event.button === 2 o 010
  4. Si fa clic sui pulsanti sinistro e destro - event.button === 3 o 011
  5. Si fa clic sul pulsante centrale - event.button === 4 o su 100
  6. Si fa clic sui pulsanti centrale e sinistro - event.button === 5 o 101
  7. Si fa clic sui pulsanti centrale e destro - event.button === 6 o 110
  8. Tutti e 3 i pulsanti vengono cliccati event.button === 7o 111

Nonostante il fatto che teoricamente dovrebbe funzionare, nessun Internet Explorer ha mai supportato i casi di due o tre pulsanti premuti contemporaneamente. Lo sto citando perché lo standard W3C non può nemmeno teoricamente supportarlo.


6
così quando si preme il pulsante si ottiene event.button === 0che non è stato cliccato alcun pulsante, IE brillanteಠ_ಠ
Sinan

È in versioni di IE inferiori a 9.
Konstantin Dinev,

Se gli sviluppatori smettessero collettivamente di scegliere di supportare ie, le persone dovrebbero cambiare, e quindi gli sviluppatori non dovrebbero più preoccuparsi di supportare ie.
ahnbizcad,

8

Mi sembra che un leggero adattamento della risposta di TheVillageIdiot sarebbe più pulito:

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

EDIT: JQuery fornisce un e.which attributo, che restituisce 1, 2, 3 rispettivamente per il clic sinistro, centrale e destro. Quindi potresti anche usareif (e.which == 3) { alert("right click"); }

Vedi anche: risposte a "Attivazione dell'evento onclick utilizzando il clic centrale"


3

event.which === 1 assicura che sia un clic sinistro (quando si utilizza jQuery).

Ma dovresti anche pensare ai tasti modificatori: ctrlcmdshiftalt

Se sei interessato solo a catturare clic semplici e non modificati, puoi fare qualcosa del genere:

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

Se stai cercando "Eventi Javascript mouse migliori" che lo consentano

  • Mousedown a sinistra
  • medio mousedown
  • giostra giusta
  • mouseup sinistro
  • mouseup centrale
  • passaggio del mouse destro
  • clic sinistro
  • clic centrale
  • tasto destro
  • rotellina del mouse verso l'alto
  • rotellina del mouse verso il basso

Dai un'occhiata a questo normale javascript tra browser che attiva gli eventi sopra elencati e rimuove il mal di testa. Basta copiarlo e incollarlo nella testa dello script o includerlo in un file nel file<head> documento. Quindi associa i tuoi eventi, fai riferimento al blocco di codice seguente che mostra un esempio jquery di acquisizione degli eventi e attivazione delle funzioni loro assegnate, sebbene funzioni anche con il normale bind JavaScript.

Se sei interessato a vederlo funzionare, dai un'occhiata a 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);
})();

Migliore esempio di eventi con clic del mouse (utilizza jquery per semplicità, ma quanto sopra funzionerà su più browser e genererà gli stessi nomi di eventi, IE utilizza prima dei nomi)

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

E per coloro che hanno bisogno della versione ridotta ...

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

Probabilmente dovresti aggiungere alcuni dettagli a al perché funziona. - Sono d'accordo che lo fa, ma non stai spiegando a un n00b perché.
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;

    }


});

@ Nitin.Katti: - Funziona sul punto del mouse e fai clic sul pulsante sinistro se blocca il pulsante sinistro del mouse, quindi interrompe il ridimensionamento.
user2335866

0

Con jquery puoi usare event object type

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

0

c'è anche un modo per farlo senza JQuery!

controlla questo:

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

Il mouse centrale sembrava 4 sul mio PC (Ubuntu 14.04 - FireFox). Credo che sinistra e destra insieme siano 3 e la media sia 4 .. Deve esserci un migliore "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");
}); 

0

A coloro che si chiedono se dovrebbero o meno usare event.whichin JS o Angular vaniglia : ora è deprecato, quindi preferisci usarlo event.buttons.

Nota: con questo metodo e l' evento (mousedown) :

  • la pressione del clic sinistro è associata a 1
  • la pressione del tasto destro del mouse è associata a 2
  • la pressione del pulsante di scorrimento è associata a 4

e l' evento (mouseup) NON restituirà gli stessi numeri ma 0 invece .

Fonte: 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
Ciao. Questa risposta viene contrassegnata come di bassa qualità per l'eliminazione. Sembra che tu abbia aggiunto una risposta a una domanda a cui è stata data risposta qualche tempo fa. A meno che non ci sia una spiegazione nella risposta che spieghi come questo contributo migliora la risposta accettata, sono propenso a votare anche per cancellare.
Popnoodles,

1
@popnoodles, va bene ma non ripeterlo mai.
Yip Man WingChun
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.