Вопрос

Есть ли способ определить, нажата ли в данный момент кнопка мыши в JavaScript?

Я знаю о событии «mousedown», но это не то, что мне нужно.Через некоторое время ПОСЛЕ нажатия кнопки мыши я хочу определить, нажата ли она еще.

Это возможно?

Это было полезно?

Решение

Что касается решения Пакса:это не работает, если пользователь намеренно или случайно нажимает более одной кнопки.Не спрашивайте меня, откуда я знаю :-(.

Правильный код должен быть таким:

var mouseDown = 0;
document.body.onmousedown = function() { 
  ++mouseDown;
}
document.body.onmouseup = function() {
  --mouseDown;
}

С таким тестом:

if(mouseDown){
  // crikey! isn't she a beauty?
}

Если вы хотите знать, какая кнопка нажата, будьте готовы сделать mouseDown массивом счетчиков и считать их отдельно для отдельных кнопок:

// let's pretend that a mouse doesn't have more than 9 buttons
var mouseDown = [0, 0, 0, 0, 0, 0, 0, 0, 0],
    mouseDownCount = 0;
document.body.onmousedown = function(evt) { 
  ++mouseDown[evt.button];
  ++mouseDownCount;
}
document.body.onmouseup = function(evt) {
  --mouseDown[evt.button];
  --mouseDownCount;
}

Теперь вы можете проверить, какие именно кнопки были нажаты:

if(mouseDownCount){
  // alright, let's lift the little bugger up!
  for(var i = 0; i < mouseDown.length; ++i){
    if(mouseDown[i]){
      // we found it right there!
    }
  }
}

Имейте в виду, что приведенный выше код будет работать только для браузеров, соответствующих стандартам, которые передают вам номер кнопки, начиная с 0 и выше.IE использует битовую маску нажатых в данный момент кнопок:

  • 0 для «ничего не нажато»
  • 1 слева
  • 2 справа
  • 4 для среднего
  • и любая комбинация вышеперечисленного, например, 5 для левого + среднего

Поэтому измените свой код соответствующим образом!Я оставляю это как упражнение.

И запомни:IE использует глобальный объект события, называемый… «событие».

Кстати, в IE есть полезная в вашем случае функция:когда другие браузеры отправляют «кнопку» только для событий кнопки мыши (onclick, onmousedown и onmouseup), IE также отправляет ее с помощью onmousemove.Таким образом, вы можете начать прослушивать onmousemove, когда вам нужно узнать состояние кнопки, и проверять evt.button, как только вы его получили — теперь вы знаете, какие кнопки мыши были нажаты:

// for IE only!
document.body.onmousemove = function(){
  if(event.button){
    // aha! we caught a feisty little sheila!
  }
};

Конечно, вы ничего не получите, если она притворится мертвой и не двигается.

Соответствующие ссылки:

Обновление №1:Я не знаю, почему я перенес код в стиле document.body.Обработчики событий лучше будет прикрепить непосредственно к документу.

Другие советы

Это старый вопрос, и ответы здесь, похоже, в основном пропагандируют использование mousedown и mouseup чтобы отслеживать, нажата ли кнопка.Но, как отмечали другие, mouseup будет срабатывать только при выполнении в браузере, что может привести к потере отслеживания состояния кнопки.

Однако, MouseEvent (сейчас) указывает, какие кнопки нажаты в данный момент:

  • Для всех современных браузеров (кроме Safari) используйте MouseEvent.buttons
  • Для Сафари используйте MouseEvent.which (buttons будет неопределенным для Safari) Примечание. which использует разные числа из buttons для правого и среднего щелчков.

При регистрации на document, mousemove сработает немедленно, как только курсор снова войдет в браузер, поэтому, если пользователь выйдет наружу, состояние будет обновлено, как только он вернется внутрь браузера.

Простая реализация может выглядеть так:

var leftMouseButtonOnlyDown = false;

function setLeftButtonState(e) {
  leftMouseButtonOnlyDown = e.buttons === undefined 
    ? e.which === 1 
    : e.buttons === 1;
}

document.body.onmousedown = setLeftButtonState;
document.body.onmousemove = setLeftButtonState;
document.body.onmouseup = setLeftButtonState;

Если требуются более сложные сценарии (разные кнопки/несколько кнопок/клавиши управления), ознакомьтесь с документацией MouseEvent.Когда/если Safari поднимет свою игру, это должно стать проще.

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

var mouseDown = 0;
document.body.onmousedown = function() { 
    mouseDown = 1;
}
document.body.onmouseup = function() {
    mouseDown = 0;
}

а затем, позже, в вашем коде:

if (mouseDown == 1) {
    // the mouse is down, do what you have to do.
}

решение не хорошее. можно было бы "опушить" на документе, затем "mouseup" вне браузера, и в этом случае браузер все еще будет думать, что мышь не работает.

единственное хорошее решение - использовать объект IE.event.

Я знаю, что это старый пост, но я подумал, что отслеживание нажатия кнопки мыши с помощью мыши вверх / вниз показалось мне немного неуклюжим, поэтому я нашел альтернативу, которая может понравиться некоторым.

<style>
    div.myDiv:active {
        cursor: default;
    }
</style>

<script>
    function handleMove( div ) {
        var style = getComputedStyle( div );
        if (style.getPropertyValue('cursor') == 'default')
        {
            // You're down and moving here!
        }
    }
</script>

<div class='myDiv' onmousemove='handleMove(this);'>Click and drag me!</div>

Селектор: active обрабатывает щелчок мыши намного лучше, чем мышь вверх / вниз, вам просто нужен способ чтения этого состояния в событии onmousemove. Для этого мне нужно было обмануть и полагаться на то, что курсором по умолчанию является «auto» и я просто изменяю его на «default», который автоматически выбирается по умолчанию.

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

Мне бы хотелось установить свой собственный стиль в разделе: active, но я не смог заставить его работать. Было бы лучше, если это возможно.

Следующий фрагмент попытается выполнить " doStuff " Функция через 2 секунды после события mouseDown в document.body. Если пользователь поднимает кнопку, происходит событие mouseUp и отменяется отложенное выполнение.

Я бы посоветовал использовать какой-нибудь метод для кросс-браузерного прикрепления событий - явная установка свойств mousedown и mouseup была сделана для упрощения примера.

function doStuff() {
  // does something when mouse is down in body for longer than 2 seconds
}

var mousedownTimeout;

document.body.onmousedown = function() { 
  mousedownTimeout = window.setTimeout(doStuff, 2000);
}

document.body.onmouseup = function() {
  window.clearTimeout(mousedownTimeout);
}

Коротко и сладко

Я не уверен, почему ни один из предыдущих ответов не работал для меня, но я придумал это решение в момент эврики. Это не только работает, но и наиболее элегантно:

Добавить к тегу тела:

onmouseup="down=0;" onmousedown="down=1;"

Затем протестируйте и выполните myfunction () , если down равно 1 :

onmousemove="if (down==1) myfunction();"

Вы можете объединить @Pax и мои ответы, чтобы также получить время, в течение которого мышь не работала:

var mousedownTimeout,
    mousedown = 0;

document.body.onmousedown = function() {
  mousedown = 0; 
  window.clearInterval(mousedownTimeout);
  mousedownTimeout = window.setInterval(function() { mousedown += 200 }, 200);
}

document.body.onmouseup = function() {
  mousedown = 0;
  window.clearInterval(mousedownTimeout);
}

Потом позже:

if (mousedown >= 2000) {
  // do something if the mousebutton has been down for at least 2 seconds
}

Вам нужно обработать MouseDown и MouseUp и установить какой-нибудь флаг или что-нибудь для его отслеживания "позже по дороге" ...: (

Используя jQuery, следующее решение обрабатывает даже «перетаскивание страницы и освобождение регистра».

$(document).mousedown(function(e) {
    mouseDown = true;
}).mouseup(function(e) {
    mouseDown = false;
}).mouseleave(function(e) {
    mouseDown = false;
});

Я не знаю, как он обрабатывает несколько кнопок мыши. Если бы был способ запустить щелчок за пределами окна, а затем ввести мышь в окно, то это, вероятно, также не будет работать должным образом.

Ниже примера jQuery, когда мышь превышает $ ('. element'), цвет меняется в зависимости от того, какая кнопка мыши нажата.

var clicableArea = {
    init: function () {
        var self = this;
        ('.element').mouseover(function (e) {
            self.handlemouseClick(e, $(this));
        }).mousedown(function (e) {
            self.handlemouseClick(e, $(this));
        });
    },
    handlemouseClick: function (e, element) {
        if (e.buttons === 1) {//left button
            element.css('background', '#f00');
        }
        if (e.buttons === 2) { //right buttom
            element.css('background', 'none');
        }
    }
};
$(document).ready(function () {
    clicableArea.init();
});

Как сказал @Jack, когда mouseup происходит за пределами окна браузера, мы об этом не знаем...

Этот код (почти) работал у меня:

window.addEventListener('mouseup', mouseUpHandler, false);
window.addEventListener('mousedown', mouseDownHandler, false);

К сожалению, я не получу mouseup событие в одном из этих случаев:

  • пользователь одновременно нажимает клавишу клавиатуры и кнопку мыши, отпускает кнопку мыши за пределами окна браузера, а затем отпускает клавишу.
  • пользователь нажимает два кнопки мыши одновременно, отпускает одну кнопку мыши, затем другую, обе за пределами окна браузера.

Если вы работаете на сложной странице с существующими обработчиками событий мыши, я бы порекомендовал обрабатывать событие при захвате (вместо пузыря). Для этого просто установите для третьего параметра addEventListener значение true .

Кроме того, вы можете проверить наличие event.which , чтобы убедиться, что вы обрабатываете фактическое взаимодействие с пользователем, а не события мыши, например, elem.dispatchEvent (новое событие ('mousedown')) .

var isMouseDown = false;

document.addEventListener('mousedown', function(event) { 
    if ( event.which ) isMouseDown = true;
}, true);

document.addEventListener('mouseup', function(event) { 
    if ( event.which ) isMouseDown = false;
}, true);

Добавление обработчика в документ (или окно) вместо document.body важно, поскольку он / она гарантирует, что события mouseup вне окна по-прежнему записываются.

Ну, вы не можете проверить, не горит ли он после события, но вы можете проверить, горит ли он ... Если он горит ... это означает, что больше не гаснет: P lol

Таким образом, пользователь нажимает кнопку вниз (событие onMouseDown) ... и после этого вы проверяете, работает ли он (onMouseUp). Пока он не работает, вы можете делать то, что вам нужно.

        var mousedown = 0;
        $(function(){
            document.onmousedown = function(e){
                mousedown = mousedown | getWindowStyleButton(e);
                e = e || window.event;
                console.log("Button: " + e.button + " Which: " + e.which + " MouseDown: " + mousedown);
            }

            document.onmouseup = function(e){
                mousedown = mousedown ^ getWindowStyleButton(e);
                e = e || window.event;
                console.log("Button: " + e.button + " Which: " + e.which + " MouseDown: " + mousedown);
            }

            document.oncontextmenu = function(e){
                // to suppress oncontextmenu because it blocks
                // a mouseup when two buttons are pressed and 
                // the right-mouse button is released before
                // the other button.
                return false;
            }
        });

        function getWindowStyleButton(e){
            var button = 0;
                if (e) {
                    if (e.button === 0) button = 1;
                    else if (e.button === 1) button = 4;
                    else if (e.button === 2) button = 2;  
                }else if (window.event){
                    button = window.event.button;
                }
            return button;
        }

эта кросс-браузерная версия отлично работает для меня.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top