Як розрізнити ліву та праву клацання миші за допомогою jQuery


574

Як отримати натиснуту кнопку миші за допомогою jQuery?

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

це спрацьовує як правою, так і лівою клавішею миші, який спосіб уловити правою клацанням миші? Я буду радий, якщо щось подібне є нижче:

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

Відповіді:


900

Станом на версію 1.1.3 jQuery, event.whichнормалізується, event.keyCodeі event.charCodeтому вам не доведеться турбуватися про проблеми сумісності браузера. Документація наevent.which

event.which дасть 1, 2 або 3 відповідно для лівої, середньої та правої кнопок миші відповідно:

$('#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, і показана тут реалізація, здається, працює нормально, але я зрозумів, що це було лише тому, що попередження () завадило появі контекстного меню. :( boo
jinglesthula

15
Дозволяє виконувати прокручування вниз і переконайтеся , що читати @ JeffHines ігрового відповіді . В основному, jQuery має цю вбудовану функцію як "контекстне меню".
jpadvo

8
@jpadvo jQuery не створив це як "контекстменю", contextmenuє вихідним з браузера. в рідному JavaScript ви можете долучити до oncontextmenuподії.
Naftali aka Neal

6
ie8: Неможливо отримати значення властивості 'that': об’єкт недійсний або невизначений
Simon

2
Чи можу я запобігти появі контекстного меню після закінчення події?
kmoney12

251

Редагувати : я змінив його на роботу для динамічно доданих елементів, використовуючи .on()jQuery 1.7 або вище:

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

Демонстрація: jsfiddle.net/Kn9s7/5

[Початок початкової публікації] Це те, що працювало для мене:

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

У випадку, якщо ви знаходитесь у кількох рішеннях ^^

Edit : Tim вниз приносить хороший момент , що це не завжди буде , right-clickщо запалює contextmenuподія, але і коли клавіша контекстного меню натискається (яке , можливо , є заміною для right-click)


28
Це має бути прийнятою відповіддю. Ця подія працює у всіх відповідних браузерах та спрацьовує на весь клік (миша вниз + миша вгору).
Нік Реталак

3
Це єдине рішення, яке працювало для мене щодо захоплення правою кнопкою миші на <textarea>
styler1972

17
Клацніть правою кнопкою миші не єдиний спосіб запустити контекстне меню.
Tim Down

3
Я думаю, що це неправильний підхід, тому що contextmenuвистріл події не завжди означає, що натискали праву кнопку миші. Правильний підхід - отримати інформацію про кнопку від події миші ( clickв даному випадку).
Тім Даун

1
Гей! Дякую, це виглядає чудово, але я не можу змусити його прив’язати до такого елемента, як ряд таблиці або навіть корпусу. він працює з $ (вікно). Я використовую backbone.js, щоб заселити область #main з новим вмістом тощо
Гаррі

84

Ви можете легко сказати, яка кнопка миші була натиснута, перевіривши whichвластивість об'єкта події на подіях миші:

/*
  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
Використовуваний вище плагін jQuery використовується e.button==2.
ceejayoz

6
так. Використання event.buttonперехресного браузера є більшою проблемою, ніж event.whichкількість номерів, які використовуються для кнопок, event.buttonрізняться. Погляньте на цю статтю з січня 2009 року - unixpapa.com/js/mouse.html
Russ Cam

1
Чи не краще це mouseupперевірити, чи людина дійсно натиснув предмет? Там багато разів, якщо я випадково натиснув щось, що я в змозі запобігти клацанню, утримуючи кнопку миші та перетягуючи її за межі елемента.
Кріс Марісіч

1
@ChrisMarisic mouseup- це, мабуть, краща подія, це лише приклад використання event.whichклацання кнопкою миші
Russ Cam

39

Ви можете також bindдо contextmenuі return false:

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

Демонстрація: http://jsfiddle.net/maniator/WS9S2/

Або ви можете зробити швидкий плагін, який робить те саме:

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

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

  };
})( jQuery );

Демо: http://jsfiddle.net/maniator/WS9S2/2/


Використання .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.

Демо: http://jsfiddle.net/maniator/WS9S2/283/


1
@Raynos так, але це єдиний спосіб обробляти подію правою кнопкою миші. якщо контекстне меню все ще було, то ви не могли нічого зробити правою кнопкою миші.
Naftali aka Neal

1
@Raynos - є багато випадків, коли ваша думка не вірна, наприклад, побудова внутрішнього інструменту або кодування чогось для вашого особистого використання. Я впевнений, що є більше
vsync

1
Якщо ви насправді хотіли, щоб він діяв як один із обробників подій jQuery (наприклад, клацніть, наприклад), це повинно бути method.call(this, e);замість method();цього способу, methodотримує правильне значення для, thisа також об'єкт події передається йому правильно.
Джеремі T

@JeremyT це правда ... ви можете обробляти зворотний дзвінок будь-яким способом ^ _ ^
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");
    }
});

Оновлення для поточного стану речей:

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
це специфічно для msie? тобто чи він портативний у інших браузерах?
Тарін Схід

13
Цей метод зараз непотрібний, як event.whichбуло введено, що виключає сумісність веб-браузера.
Жолудь

8
Я підозрюю, що event.wich фактично усуває несумісність між веб-переглядачами, але це лише я.
DwB


15

Є дуже багато хороших відповідей, але я просто хочу торкнутися однієї основної різниці між IE9 та IE <9 при використанні event.button .

Відповідно до старої специфікації Microsoft event.buttonкоди відрізняються від тих, що використовуються W3C. W3C розглядає лише 3 випадки:

  1. Клацається ліва кнопка миші - event.button === 1
  2. Клацається правою кнопкою миші - event.button === 3
  3. Натискається середня кнопка миші - event.button === 2

Однак у старших Інтернет-дослідників Microsoft трохи натискає натиснуту кнопку, і є 8 випадків:

  1. Не натискається жодна кнопка - event.button === 0 або 000
  2. Клацніть ліву кнопку - event.button === 1 або 001
  3. Клацніть правою кнопкою - event.button === 2 або 010
  4. Клацають ліву і праву кнопки - event.button === 3 або 011
  5. Натискається середня кнопка - event.button === 4 або 100
  6. Клацають середню та ліву кнопки - event.button === 5 або 101
  7. Клацають середні та праві кнопки - event.button === 6 або 110
  8. Натискаються всі 3 кнопки - event.button === 7або 111

Незважаючи на те, що теоретично це має працювати, жоден Internet Explorer ніколи не підтримував випадки одночасного натискання двох або трьох кнопок. Я згадую це, тому що стандарт W3C навіть теоретично не може цього підтвердити.


6
тож після натиснутої кнопки ви отримуєте event.button === 0яку не натиснуто жодної кнопки, блискучий IEಠ_ಠ
Сінан

Це у версіях IE нижче 9.
Костянтин Дінев

Якщо розробники колективно перестали обирати підтримку, тобто люди повинні були б перейти, і тоді розробникам більше не доведеться турбуватися про підтримку, тобто.
ahnbizcad

8

Мені здається, що незначна адаптація відповіді TheVillageIdiot була б більш чистою:

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

EDIT: JQuery надає e.whichатрибут, повертаючи 1, 2, 3 для лівого, середнього та правого клацання відповідно. Тож ви також могли використовуватиif (e.which == 3) { alert("right click"); }

Дивіться також: відповіді на "Запуск події onclick за допомогою середнього клацання"


3

event.which === 1 забезпечує його клацання лівою кнопкою миші (при використанні jQuery).

Але також слід подумати про модифікаційні клавіші: ctrlcmdshiftalt

Якщо вас цікавить лише простий, немодифікований лівий клацання, ви можете зробити щось подібне:

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

Якщо ви шукаєте "Кращі події миші в JavaScript", які дозволяють

  • ліворуч
  • середня мусота
  • правильна мусея
  • ліва миша
  • середня миша
  • права миша
  • клацання лівою кнопкою миші
  • середній клацання
  • клацніть правою кнопкою миші
  • мишоловка вгору
  • мишоловка вниз

Подивіться на цей крос-браузер звичайний javascript, який запускає вищевказані події та знімає головний біль. Просто скопіюйте та вставте його в голову сценарію або включіть його у файл у<head> своєму документі. Потім зв’яжіть свої події, зверніться до наступного блоку коду нижче, де показаний приклад jquery зйомки подій та запуску призначених їм функцій, хоча це працює і при звичайному прив'язці JavaScript.

Якщо ви зацікавлені в тому, щоб це працювало, подивіться на 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);
})();

Приклад "Поліпшення клацання мишею" Приклад подій (використовує jquery для простоти, але вищезгадане буде працювати перехресним браузером та запускати ті самі імена подій, які IE використовує перед іменами)

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

А для тих, хто потребує мінімізованої версії ...

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

Напевно, ви повинні додати деякі деталі, чому це працює. - Я згоден, що це так, але ви не пояснюєте n00b чому.
Адам Коплі

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: - Це робота над точкою миші та натисканням лівої кнопки, якщо заморозити ліву кнопку миші, то вона зупинить повторне розмір.
користувач2335866

0

За допомогою jquery ви можете використовувати event object type

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

0

також є спосіб зробити це без JQuery!

перевірити це:

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

Середній миші здавався 4 на моєму ПК (Ubuntu 14.04 - FireFox). Я вважаю, що ліворуч і праворуч - 3, а середина - 4. Має бути кращий "крос-браузер", "кросова платформа" спосіб ...
Павло

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

Тим, хто задається питанням, чи варто їх використовувати чи не використовувати event.whichу ванільній JS або Angular : Це тепер застаріле, тому краще використовувати event.buttonsзамість цього.

Примітка. За допомогою цього методу та (mousedown) події:

  • натискання лівою кнопкою миші пов'язане з 1
  • натискання правою кнопкою миші пов'язане з 2
  • натискання кнопки прокрутки пов'язане з 4

і (миша) подія НЕ поверне ті самі числа, а лише 0 .

Джерело: 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
Привіт. Ця відповідь позначена як низька якість для видалення. Здається, ви додали відповідь на питання, на яке було відповідено деякий час тому. Якщо у відповіді немає пояснення, яке пояснює, як цей внесок покращує прийняту відповідь, я схильний голосувати і за видалення.
Popnoodles

1
@popnoodles, це добре, але ніколи не повторюйте.
Yip Man WingChun
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.