Cara membedakan antara klik kiri dan kanan mouse dengan jQuery

574

Bagaimana Anda mendapatkan tombol mouse yang diklik menggunakan jQuery?

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

ini dipicu oleh klik kanan dan kiri, bagaimana cara menangkap klik kanan mouse? Saya akan senang jika sesuatu seperti di bawah ini ada:

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

Jawaban:

900

Pada jQuery versi 1.1.3, event.whichmenormalkan event.keyCodedan event.charCodesehingga Anda tidak perlu khawatir tentang masalah kompatibilitas browser. Dokumentasi tentangevent.which

event.which akan memberikan 1, 2 atau 3 untuk masing-masing tombol kiri, tengah dan kanan sehingga:

$('#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!');
    }
});
Biji pohon ek
sumber
4
@Jeff Hines - Saya mencoba mendeteksi klik kanan di Chrome dan implementasi yang ditampilkan di sini tampaknya berfungsi dengan baik, tetapi saya menyadari bahwa itu hanya karena peringatan () mencegah menu konteks muncul. :( boo
jinglesthula
15
Terus gulir ke bawah dan pastikan untuk membaca jawaban @ JeffHines . Pada dasarnya, jQuery memiliki built-in ini sebagai event 'contextmenu'.
jpadvo
8
@ jpadvo jQuery tidak membangunnya sebagai "contextmenu", contextmenuadalah asli browser. dalam JavaScript asli Anda dapat melampirkan ke oncontextmenuacara tersebut.
Naftali alias Neal
6
ie8: Tidak dapat mendapatkan nilai dari properti 'yang': objek adalah nol atau tidak terdefinisi
Simon
2
Bisakah saya mencegah menu konteks muncul setelah acara dipecat?
kmoney12
251

Sunting : Saya mengubahnya agar berfungsi untuk elemen yang ditambahkan secara dinamis menggunakan .on()di jQuery 1.7 atau lebih tinggi:

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

Demo: jsfiddle.net/Kn9s7/5

[Mulai posting asli] Inilah yang bekerja untuk saya:

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

Jika Anda tertarik pada banyak solusi ^^

Sunting : Tim Down memunculkan poin yang baik bahwa itu tidak selalu akan menjadi peristiwa right-clickyang memicu contextmenu, tetapi juga ketika tombol menu konteks ditekan (yang bisa dibilang pengganti untuk a right-click)

Jeff Hines
sumber
28
Ini harus menjadi jawaban yang diterima. Acara ini berfungsi di semua browser dan pemicu yang relevan pada satu klik penuh (tetikus + tetikus ke atas dalam jarak dekat).
Nick Retallack
3
Ini adalah satu - satunya solusi yang bekerja untuk saya dalam hal menangkap klik kanan pada <textarea>
styler1972
17
Mengklik kanan bukan satu-satunya cara untuk memicu menu konteks.
Tim Down
3
Saya pikir itu pendekatan yang salah karena contextmenuperistiwa penembakan tidak selalu menyiratkan bahwa tombol mouse kanan diklik. Pendekatan yang benar adalah mendapatkan informasi tombol dari acara mouse ( clickdalam hal ini).
Tim Down
1
Hei! Terima kasih, ini terlihat hebat, tapi saya tidak bisa mengikatnya ke elemen seperti baris tabel atau bahkan badan. ini bekerja dengan $ (jendela). Saya menggunakan backbone.js untuk mengisi area #main dengan konten baru, dll.
Harry
84

Anda dapat dengan mudah mengetahui tombol mouse mana yang ditekan dengan memeriksa whichproperti objek acara pada peristiwa 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! */
    }
});
Russ Cam
sumber
3
Plugin jQuery yang ditautkan di atas menggunakan e.button==2sebaliknya.
ceejayoz
6
ya. Menggunakan event.buttonlintas browser lebih merupakan masalah daripada event.whichangka yang digunakan untuk berbagai tombol event.button. Lihatlah artikel ini dari Januari 2009 - unixpapa.com/js/mouse.html
Russ Cam
1
Bukankah ini lebih baik mouseupuntuk memverifikasi seseorang benar-benar mengklik item? Ada banyak waktu jika saya tidak sengaja mengklik sesuatu, saya dapat mencegah klik dengan menahan tombol mouse dan menyeret keluar elemen.
Chris Marisic
1
@ChrisMarisic mouseupmungkin adalah acara yang lebih baik, ini hanya contoh dari penggunaan event.whichklik tombol mouse
Russ Cam
39

Anda juga dapat bindke contextmenudan return false:

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

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

Atau Anda dapat membuat plugin cepat yang melakukan hal yang sama:

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

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

  };
})( jQuery );

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


Menggunakan .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/

Naftali alias Neal
sumber
1
@ Raynos ya, tapi itu satu-satunya cara untuk menangani acara klik kanan. jika menu konteks masih ada maka Anda tidak dapat melakukan apa-apa dengan klik kanan.
Naftali alias Neal
1
@ Raynos - ada banyak kasus di mana poin Anda tidak valid, seperti membangun alat internal, atau mengkode sesuatu untuk penggunaan pribadi Anda sendiri .. Saya yakin ada lebih banyak
vsync
1
Jika Anda benar-benar ingin itu bertindak seperti salah satu penangan acara jQuery (seperti klik, misalnya), yang seharusnya method.call(this, e);bukan dengan method();cara itu, methodmendapatkan nilai yang benar untuk thisdan juga memiliki objek acara diteruskan dengan benar.
Jeremy T
@JeremyT itu benar ... Anda bisa menangani panggilan balik dengan cara apa pun yang Anda inginkan ^ _ ^
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");
    }
});

Perbarui keadaan saat ini:

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
sumber
1
apakah ini khusus msie? yaitu apakah portable di browser lain?
Taryn East
13
Metode ini sekarang tidak perlu seperti yang event.whichtelah diperkenalkan yang menghilangkan kompatibilitas lintas browser.
Acorn
8
Saya curiga ada event.yang sebenarnya menghilangkan ketidakcocokan lintas browser, tapi itu hanya saya.
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
sumber
15

Ada banyak jawaban yang sangat bagus, tetapi saya hanya ingin menyentuh satu perbedaan utama antara IE9 dan IE <9 saat menggunakan event.button.

Menurut spesifikasi Microsoft lama untuk event.buttonkode berbeda dari yang digunakan oleh W3C. W3C hanya mempertimbangkan 3 kasus:

  1. Tombol kiri mouse diklik - event.button === 1
  2. Tombol kanan mouse diklik - event.button === 3
  3. Tombol tengah mouse diklik - event.button === 2

Dalam Internet Explorer yang lebih lama namun Microsoft sedikit membalik untuk tombol yang ditekan dan ada 8 kasus:

  1. Tidak ada tombol yang diklik - event.button === 0atau 000
  2. Tombol kiri diklik - event.button === 1atau 001
  3. Tombol kanan diklik - event.button === 2atau 010
  4. Tombol kiri dan kanan diklik - event.button === 3atau 011
  5. Tombol tengah diklik - event.button === 4atau 100
  6. Tombol tengah dan kiri diklik - event.button === 5atau 101
  7. Tombol tengah dan kanan diklik - event.button === 6atau 110
  8. Semua 3 tombol diklik - event.button === 7atau 111

Terlepas dari kenyataan bahwa ini secara teoritis bagaimana seharusnya bekerja, tidak ada Internet Explorer yang pernah mendukung kasus dua atau tiga tombol yang ditekan secara bersamaan. Saya menyebutkannya karena standar W3C bahkan tidak dapat secara teoritis mendukung ini.

Konstantin Dinev
sumber
6
jadi setelah menekan tombol Anda mendapatkan tombol event.button === 0yang tidak diklik, brilian IEಠ_ಠ
Sinan
Itu dalam versi IE yang lebih rendah dari 9.
Konstantin Dinev
Jika pengembang secara kolektif berhenti memilih untuk mendukung yaitu, orang harus beralih, dan kemudian pengembang tidak perlu lagi khawatir tentang mendukung yaitu.
ahnbizcad
8

Sepertinya saya sedikit adaptasi dari jawaban TheVillageIdiot akan lebih bersih:

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

EDIT: JQuery memberikan e.whichatribut, masing-masing mengembalikan 1, 2, 3 untuk klik kiri, tengah, dan kanan. Jadi bisa juga Anda gunakanif (e.which == 3) { alert("right click"); }

Lihat juga: jawaban untuk "Memicu acara klik menggunakan klik tengah"

Dan Burton
sumber
3

event.which === 1 memastikan itu klik kiri (saat menggunakan jQuery).

Tetapi Anda juga harus memikirkan kunci pengubah: ctrlcmdshiftalt

Jika Anda hanya tertarik untuk menangkap klik kiri yang sederhana dan tidak dimodifikasi, Anda dapat melakukan sesuatu seperti ini:

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

Jika Anda mencari "Acara Mouse Javascript Lebih Baik" yang memungkinkan

  • meninggalkan tikus
  • tengah musim gugur
  • mousedown benar
  • mouseup kiri
  • mouseup tengah
  • mouseup kanan
  • klik kiri
  • klik tengah
  • klik kanan
  • roda mouse ke atas
  • roda mouse ke bawah

Lihat javascript normal peramban silang ini yang memicu peristiwa di atas, dan menghilangkan pekerjaan sakit kepala. Cukup salin dan tempel ke bagian atas skrip Anda, atau sertakan dalam file di dalam <head>dokumen Anda. Kemudian ikat acara Anda, lihat blok kode berikut di bawah ini yang menunjukkan contoh jquery menangkap peristiwa dan menjalankan fungsi yang ditugaskan untuk mereka, meskipun ini bekerja dengan javascript mengikat normal juga.

Jika Anda tertarik melihatnya berfungsi, lihat 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);
})();

Contoh Acara Klik Mouse yang Lebih Baik (menggunakan jquery untuk kesederhanaan, tetapi di atas akan bekerja lintas browser dan mem-api nama acara yang sama, IE menggunakan sebelum nama-nama)

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

Dan bagi mereka yang membutuhkan versi yang diperkecil ...

!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
sumber
1
$("body").on({
    click: function(){alert("left click");},
    contextmenu: function(){alert("right click");}   
});
AK
sumber
Anda mungkin harus menambahkan beberapa detail mengapa itu bekerja. - Saya setuju itu terjadi, tetapi Anda tidak menjelaskan kepada n00b mengapa.
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;

    }


});
pengguna2335866
sumber
@ Nitin.Katti: - Ini berfungsi pada titik mouse dan klik tombol kiri jika membekukan tombol kiri mouse maka itu menghentikan ukuran kembali.
user2335866
0

Dengan jquery bisa Anda gunakan event object type

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

ada juga cara, untuk melakukannya tanpa JQuery!

Lihat ini:

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

sumber
Mouse tengah tampak 4 di PC saya (Ubuntu 14.04 - FireFox). Saya percaya kiri dan kanan bersama-sama adalah 3 dan tengah adalah 4 .. Harus ada cara "cross browser" yang lebih baik, "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");
}); 
pengguna3361174
sumber
0

Bagi mereka yang bertanya-tanya apakah mereka harus menggunakan atau tidak event.whichdalam vanilla JS atau Angular : Sekarang sudah usang jadi lebih suka menggunakan event.buttonssebagai gantinya.

Catatan: Dengan metode ini dan acara (mousedown) :

  • klik kiri pers dikaitkan dengan 1
  • klik kanan pers dikaitkan dengan 2
  • tombol gulir, tekan dikaitkan dengan 4

dan acara (mouseup) TIDAK akan mengembalikan angka yang sama tetapi 0 sebagai gantinya.

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

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

   $(document).on("rightclick", "div", function() {
   console.log("hello");
    return false;
    });
Yip Man WingChun
sumber
1
Hai. Jawaban ini ditandai sebagai kualitas rendah untuk dihapus. Sepertinya Anda telah menambahkan jawaban untuk pertanyaan yang dijawab beberapa waktu lalu. Kecuali ada penjelasan dalam jawaban yang menjelaskan bagaimana kontribusi ini meningkatkan jawaban yang diterima, saya cenderung memilih untuk menghapus juga.
Popnoodles
1
@popnoodles, tidak apa-apa tetapi tidak pernah mengulanginya.
Yip Man WingChun