JQuery ile sol ve sağ fare tıklaması arasında nasıl ayrım yapılır?


574

Tıklanan fare düğmesini jQuery kullanarak nasıl edinebilirsiniz?

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

bu hem sağ hem de sol tıklama ile tetiklenir, sağ fare tıklamasını yakalamanın yolu nedir? Aşağıdaki gibi bir şey varsa mutlu olurum:

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

Yanıtlar:


900

JQuery sürüm 1.1.3'ten itibaren event.whichnormalleşir event.keyCodeve event.charCodebu nedenle tarayıcı uyumluluğu sorunları hakkında endişelenmenize gerek yoktur. Üzerindeki belgelerevent.which

event.which sol, orta ve sağ fare düğmeleri için sırasıyla 1, 2 veya 3 verecektir:

$('#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 - Chrome'da sağ bir tıklamayı tespit etmeye çalışıyordum ve burada gösterilen uygulama iyi çalışıyor gibi göründü, ancak bunun yalnızca alert () öğesinin bağlam menüsünün görünmesini engellediği için olduğunu fark ettim. :( boo
jinglesthula

15
Aşağı kaydırmaya devam edin ve @ JeffHines'ın cevabını okuduğunuzdan emin olun . Temel olarak, jQuery yerleşik olarak 'contextmenu' olayına sahiptir.
jpadvo

8
@jpadvo jQuery bunu "contextmenu" olarak inşa etmedi contextmenu, tarayıcıya özgü. yerel JavaScript'te oncontextmenuetkinliğe ekleyebilirsiniz .
Naftali aka Neal

6
ie8: 'which' özelliğinin değeri alınamıyor: nesne null veya undefined
Simon

2
Etkinlik tetiklendikten sonra içerik menüsünün görünmesini engelleyebilir miyim?
kmoney12

251

Düzenleme : Ben .on()jQuery 1.7 veya üstü kullanarak dinamik olarak eklenen öğeler için çalışmak için değiştirdim :

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

Demo: jsfiddle.net/Kn9s7/5

Benim için işe yarayan şey budur:

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

Birden fazla çözümün olması durumunda ^^

Düzenleme : Tim Down her zaman olayı right-clicktetikleyecek contextmenudeğil, aynı zamanda bağlam menüsü tuşuna basıldığında da iyi bir nokta getirir (bu muhtemelen a'nın yerine geçer right-click)


28
Bu kabul edilen cevap olmalı. Bu etkinlik, ilgili tüm tarayıcılarda çalışır ve tüm tıklamayla tetiklenir (fare aşağı + yakın fare yukarı).
Nick Retallack

3
Bu sadece bir <textarea> sağ klik yakalama açısından benim için çalıştı çözüm
styler1972

17
Sağ tıklama, bağlam menüsünü tetiklemenin tek yolu değildir.
Tim Down

3
Bence bu yanlış bir yaklaşım çünkü contextmenuolay ateşleme her zaman sağ fare düğmesine tıklandığını ima etmiyor. Doğru yaklaşım, bir fare olayından ( clickbu durumda) düğme bilgilerini almaktır .
Tim Down

1
Hey! Teşekkürler, bu harika görünüyor, ancak tablo satırı veya hatta vücut gibi bir öğeye bağlanmasını sağlayamıyorum. $ (window) ile çalışır. #Bone ile yeni içerik vb alan doldurmak için backbone.js kullanıyorum
Harry

84

whichFare olaylarında olay nesnesinin özelliğini kontrol ederek hangi fare düğmesine basıldığını kolayca anlayabilirsiniz :

/*
  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
Yukarıda bağlı jQuery eklentisi kullanıyor e.button==2.
ceejayoz

6
Evet. event.buttonÇapraz tarayıcı kullanmak event.which, düğmeler için kullanılan numaraların event.buttonfarklılık göstermesinden daha fazla bir sorundur . Ocak 2009'dan bu makaleye bir göz atın - unixpapa.com/js/mouse.html
Russ Cam

1
mouseupBir kişinin öğeyi gerçekten tıkladığını doğrulamak daha iyi olmaz mıydı ? Yanlışlıkla fare düğmesini basılı tutarak ve öğenin dışına sürükleyerek tıklamayı engelleyebileceğim bir şey tıklarsam birçok kez vardır.
Chris Marisic

1
@ChrisMarisic mouseupmuhtemelen daha iyi bir olay, bu sadece event.whichfare düğmesi tıklamalarının kullanımının bir örneğidir
Russ Cam

39

Ayrıca şunları yapabilirsiniz bindiçin contextmenuve return false:

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

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

Ya da aynı şeyi yapan hızlı bir eklenti yapabilirsiniz:

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

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

  };
})( jQuery );

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


.on(...)JQuery> = 1.7 kullanarak :

$(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
@ Evetos evet, ancak sağ tıklama olayını işlemenin tek yolu bu. bağlam menüsü hala oradaysa, sağ tıklama ile hiçbir şey yapamazsınız.
Naftali aka Neal

1
@Raynos - dahili bir araç oluşturmak veya kendi kişisel kullanımınız için bir şey kodlamak gibi, puanınızın geçerli olmadığı birçok durum var ... Eminim daha fazlası var
vsync

1
Aslında o (örneğin, tıklama gibi) jQuery olay işleyicileri biri gibi davranmaya istiyorsa, o olmalı method.call(this, e);yerine method();, bu arada, methodiçin doğru değeri alır thisve ayrıca doğru kendisine geçirilen olay nesnesi vardır.
Jeremy T

@JeremyT bu doğru ... geri aramayı istediğiniz herhangi bir şekilde halledebilirsiniz ^ _ ^
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");
    }
});

Olayların mevcut durumu için güncelleme:

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
Bu msie'ye özgü mü? yani diğer tarayıcılarda taşınabilir mi?
Taryn East

13
Bu yöntem artık event.whichçapraz tarayıcı uyumluluğunu ortadan kaldıran gereksizdir .
Acorn

8
Çapraz tarayıcı uyumsuzluğunu gerçekten ortadan kaldıran olaydan şüpheleniyorum, ama bu sadece benim.
DwB

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

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

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


15

Çok iyi cevaplar var, ancak IE9 ve IE <9 arasındaki büyük bir farka dokunmak istiyorum event.button.

event.buttonKodlar için eski Microsoft spesifikasyonuna göre W3C tarafından kullanılanlardan farklıdır. W3C sadece 3 vakayı dikkate alır:

  1. Sol fare düğmesi tıklandı - event.button === 1
  2. Sağ fare düğmesi tıklanır - event.button === 3
  3. Farenin orta düğmesi tıklandı - event.button === 2

Ancak eski Internet Explorer'larda Microsoft, basılan düğmeyi biraz çeviriyor ve 8 durum var:

  1. Hiçbir düğme tıklanmaz - event.button === 0veya 000
  2. Sol düğme tıklatılır - event.button === 1veya 001
  3. Sağ düğme tıklatılır - event.button === 2veya 010
  4. Sol ve sağ düğmeler tıklanır - event.button === 3veya 011
  5. Ortadaki düğme tıklandı - event.button === 4veya 100
  6. Orta ve sol düğmeler tıklanır - event.button === 5veya 101
  7. Orta ve sağ düğmeler tıklanır - event.button === 6veya 110
  8. 3 düğmenin tümü tıklanır - event.button === 7veya 111

Teorik olarak nasıl çalışması gerektiği gerçeğine rağmen, hiçbir Internet Explorer aynı anda basılan iki veya üç düğmenin vakalarını desteklemedi. Bahsetmiyorum çünkü W3C standardı teorik olarak bunu bile destekleyemiyor.


6
bu yüzden basılan düğmeye basıldığında elde edersiniz event.button === 0, parlak IEಠ_ಠ
Sinan


Geliştiriciler toplu olarak desteklemeyi seçmeyi durdurursa, yani insanlar geçiş yapmak zorunda kalacaklar ve daha sonra geliştiriciler artık destekleme konusunda endişelenmek zorunda kalmayacaklardı.
ahnbizcad

8

Bana öyle geliyor ki TheVillageIdiot'un cevabının hafif bir uyarlaması daha temiz olurdu:

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

EDIT: JQuery e.whichsırasıyla sol, orta ve sağ tıklama için 1, 2, 3 döndüren bir özellik sağlar . Böylece kullanabilirsinizif (e.which == 3) { alert("right click"); }

Ayrıca bkz: "Orta tıklamayı kullanarak onclick etkinliğini tetikleme" yanıtları


3

event.which === 1 sol tıklama olmasını sağlar (jQuery kullanırken).

Ancak, değiştirici tuşları da düşünmelisiniz: ctrlcmdshiftalt

Yalnızca basit, değiştirilmemiş sol tıklamaları yakalamakla ilgileniyorsanız, şöyle bir şey yapabilirsiniz:

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

Eğer izin "Better Javascript Fare Olaylar" arıyorsanız

  • fareyle ayrıldı
  • orta mousedown
  • sağ fareyle
  • sol fare
  • orta fare
  • sağ fare
  • sol tık
  • Orta tıklama
  • sağ tık
  • fare tekerleği yukarı
  • fare tekerleği aşağı

Yukarıdaki olayları tetikleyen ve baş ağrısı işini kaldıran bu çapraz tarayıcı normal javascript bir göz atın. Sadece kopyalayıp komut dosyanızın başına yapıştırın veya <head>belgenizdeki bir dosyaya ekleyin. Ardından, etkinliklerinizi bağlayın, normal javascript bağlamasıyla da çalışmasına rağmen, olayları yakalamak ve kendilerine atanan işlevleri tetiklemek için bir jquery örneği gösteren bir sonraki kod bloğuna bakın.

Çalıştığını görmekle ilgileniyorsanız, jsFiddle'a bakın: 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);
})();

Daha İyi Fare Tıklama Olayları Örneği (basitlik için jquery kullanır, ancak yukarıdaki çapraz tarayıcıda çalışır ve aynı olay adlarını tetikler, IE adlardan önce kullanır)

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

Ve küçültülmüş versiyona ihtiyaç duyanlar için ...

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

Muhtemelen neden işe yaradığına dair bazı ayrıntılar eklemelisiniz. - Kabul ediyorum, ama neden bir n00b'ye açıklamıyorsun.
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: - Bu fare noktası üzerinde çalışmak ve farenin sol düğmesini dondurursanız sol düğme tıklayın sonra yeniden boyutlandırma durdurmak.
user2335866

0

Jquery ile kullanabilirsiniz event object type

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

0

JQuery olmadan bunu yapmanın bir yolu da var!

bunu kontrol et:

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

Orta fare bilgisayarımda 4 gibiydi (Ubuntu 14.04 - FireFox). Ben sol ve sağ birlikte 3 ve orta 4 olduğuna inanıyorum .. Daha iyi bir "çapraz tarayıcı", "çapraz platform" yolu olmalı ...
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

Kendilerinin ya kullanmamalısınız eğer o merak edenler event.whichiçinde vanilya JS veya açısal : Şimdi oluyor kaldırılmış böylece kullanmayı tercih event.buttonsyerine.

Not: Bu yöntem ve (mousedown) etkinliği ile:

  • left click press 1 ile ilişkili
  • right click press 2 ile ilişkilendirilir
  • scroll button press 4 ile ilişkili

ve (mouseup) olay olacak DEĞİL aynı numaraları ama dönmek 0 yerine.

Kaynak: 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
Selam. Bu yanıt, silinmek üzere düşük kalite olarak işaretleniyor. Görünüşe göre bir süre önce cevaplanmış bir soruya cevap eklediniz. Cevapta bu katkının kabul edilen cevabı nasıl geliştirdiğini açıklayan bir açıklama olmadığı sürece, ben de silmeye oy vermeye meyilliyim.
Popnoodles

1
@popnoodles, sorun değil ama asla tekrar etmeyin.
Yip Man WingChun
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.