JQuery: обнаружение нажатой кнопки мыши во время события mousemove

Я попытался обнаружить, какая кнопка мыши - если любой пользователь нажимает во время события mousemove в jQuery, но я получаю неоднозначные результаты:

no button pressed:      e.which = 1   e.button = 0
left button pressed:    e.which = 1   e.button = 0
middle button pressed:  e.which = 2   e.button = 1
right button pressed:   e.which = 3   e.button = 2

код:

<!DOCTYPE html>
<html>
<head>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
</head>
<body>

<input id="whichkey" value="type something">
<div id="log"></div>
<script>$('#whichkey').bind('mousemove',function(e){ 
  $('#log').html(e.which + ' : ' +  e.button );
});  </script>

</body>
</html>

Как я могу сказать разницу между нажатой левой кнопкой мыши и кнопкой вообще?

Ответ 1

Вы можете написать немного кода, чтобы отслеживать состояние левой кнопки мыши, и с небольшой функцией вы можете предварительно обработать переменную события в событии mousemove.

Чтобы отслеживать состояние LMB, привяжите событие к уровню документа для mousedown и mouseup и установите флажок e.which для установки или очистки флага.

Предварительная обработка выполняется с помощью функции tweakMouseMoveEvent() в моем коде. Для поддержки версий IE < 9, вы должны проверить, были ли кнопки мыши выпущены за пределами окна и очистить флаг, если это так. Затем вы можете изменить переданную переменную события. Если e.which изначально был 1 (без кнопки или LMB), и текущее состояние левой кнопки не нажато, просто установите e.which в 0 и используйте это в остальной части вашего mousemove события, чтобы проверить кнопки не нажаты.

Обработчик mousemove в моем примере просто вызывает функцию tweak, передающую текущую переменную события, затем выводит значение e.which.

$(function() {
    var leftButtonDown = false;
    $(document).mousedown(function(e){
        // Left mouse button was pressed, set flag
        if(e.which === 1) leftButtonDown = true;
    });
    $(document).mouseup(function(e){
        // Left mouse button was released, clear flag
        if(e.which === 1) leftButtonDown = false;
    });

    function tweakMouseMoveEvent(e){
        // Check from jQuery UI for IE versions < 9
        if ($.browser.msie && !e.button && !(document.documentMode >= 9)) {
            leftButtonDown = false;
        }

        // If left button is not set, set which to 0
        // This indicates no buttons pressed
        if(e.which === 1 && !leftButtonDown) e.which = 0;
    }

    $(document).mousemove(function(e) {
        // Call the tweak function to check for LMB and set correct e.which
        tweakMouseMoveEvent(e);

        $('body').text('which: ' + e.which);
    });
});

Попробуйте демо-версию здесь: http://jsfiddle.net/G5Xr2/

Ответ 2

Большинство браузеров (кроме Safari) *) теперь поддерживают свойство MouseEvent.buttons (примечание: множественное число) s "), который равен 1 при нажатии левой кнопки мыши:

$('#whichkey').bind('mousemove', function(e) { 
    $('#log').html('Pressed: ' + e.buttons);
});

https://jsfiddle.net/pdz2nzon/2

<я > *) Мир движется вперед:
https://webkit.org/blog/8016/release-notes-for-safari-technology-preview-43/
https://trac.webkit.org/changeset/223264/webkit/

Ответ 3

По какой-то причине при привязке к событию mousemove для свойства event.which установлено значение 1, если нажата левая кнопка или нет.

Я изменил на mousedown событие, и он работал Ok:

  • left: 1
  • средний: 2
  • справа: 3

Вот рабочий пример: http://jsfiddle.net/marcosfromero/RrXbX/

Код jQuery:

$('p').mousedown(function(event) {
    console.log(event.which);
    $('#button').text(event.which);
});

Ответ 4

jQuery нормализует значение which, поэтому он будет работать во всех браузерах. Бьюсь об заклад, если вы запустите свой script, вы найдете разные значения e.button.

Ответ 5

Эти переменные обновляются, когда срабатывает событие mousedown (среди других); вы видите значение, которое остается от этого события. Обратите внимание, что они являются свойствами этого события, а не самой мыши:

Описание: Для событий ключа или кнопки этот атрибут указывает конкретную кнопку или клавишу, которая была нажата.

Нет значения для "no button press", потому что событие mousedown никогда не срабатывает, чтобы указать, что кнопка не нажата.

Вам нужно будет сохранить свою собственную глобальную переменную [boolean] и включить/выключить ее на mousedown/mouseup.

  • Это будет работать, только если окно браузера было сфокусировано при нажатии кнопки, что означает, что переключатель фокусировки между нажатием кнопки мыши и нажатием кнопки mousemove предотвратит ее правильную работу. Тем не менее, вы действительно не можете сделать этого.

Ответ 6

Начиная с даты, в Firefox 47, Chrome 54 и Safari 10 работают следующие.

$('#whichkey').bind('mousemove',function(e){
    if (e.buttons & 1 || (e.buttons === undefined && e.which == 1)) {
        $('#log').html('left button pressed');
    } else if (e.buttons & 2 || (e.buttons === undefined && e.which == 3)) {
        $('#log').html('right button pressed');
    } else {
        $('#log').html('no button pressed');
    }
});

Ответ 7

Для пользователей, которые ищут подобное решение, но без использования JQuery, вот как я решил свою проблему:

    canvas.addEventListener("mousemove", updatePosition_mouseNtouch);

    function updatePosition_mouseNtouch (evt) {
      // IF mouse is down THEN set button press flag
      if(evt.which === 1)
        leftButtonDown = true;
      // If you need to detect other buttons, then make this here
      // ... else if(evt.which === 2) middleButtonDown = true;
      // ... else if(evt.which === 3) rightButtonDown = true;
      // IF no mouse button is pressed THEN reset press flag(s)
      else
        leftButtonDown = false;

      if (leftButtonDown) {
        /* do some stuff */
      }
    }

Надеюсь, это полезно для кого-то, кто ищет ответ.