JavaScript: проверьте, если кнопка мыши вниз?
есть ли способ определить, если кнопка мыши в настоящее время вниз в JavaScript?
Я знаю о событии "mousedown", но это не то, что мне нужно. Через некоторое время после нажатия кнопки мыши, я хочу быть в состоянии определить, если он по-прежнему нажата.
это возможно?
15 ответов:
Что касается решения Pax: он не работает, если пользователь нажимает более одной кнопки намеренно или случайно. Не спрашивайте меня, откуда я знаю : - (.
правильный код должен быть таким:
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 и выше. Т. е. использует немного маски в настоящее время нажатой кнопки:
- 0 Для "ничего не нажата"
- 1 слева
- 2 справа
- 4 для среднего
- и любая комбинация выше, например, 5 для левого + среднего
так настроить свой код соответственно! Я оставляю это как упражнение.
и помните: IE использует глобальный объект события под названием ... "событие".
кстати IE имеет функцию, полезную в вашем случае: когда другие браузеры отправляют "кнопку" только для событий кнопки мыши (onclick, onmousedown и onmouseup), IE отправляет его с onmousemove тоже. Таким образом, вы можете начать прослушивание onmousemove, когда вам нужно знать состояние кнопки, и проверить наличие evt.кнопка, как только вы получили его-теперь вы знаете, что мышь были нажаты кнопки:
// for IE only! document.body.onmousemove = function(){ if(event.button){ // aha! we caught a feisty little sheila! } };
конечно, вы ничего не получите, если она притворяется мертвой и не двигается.
полезные ссылки:
обновление #1: я не знаю, почему я перенес документ.тело-стиль кода. Будет лучше прикрепить обработчики событий непосредственно к документу.
Я думаю, что лучший подход к этому, чтобы сохранить свою собственную запись состояния кнопки мыши, следующим образом:
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. }
решение не очень хорошее. можно было бы " mousedown "на документе, а затем" mouseup " вне браузера, и в этом случае браузер все равно будет думать, что мышь не работает.
единственным хорошим решением является использование IE.объект события.
это старый вопрос, и ответ здесь, кажется, в основном выступают за использование
, MouseEvent (сейчас) указывает, какие кнопки в данный момент нажаты:mousedown
иmouseup
чтобы отслеживать, нажата ли кнопка. Но, как указывали другие,mouseup
будет срабатывать только при выполнении в браузере, что может привести к потере отслеживания состояния кнопки.
- для всех современных браузеров (кроме Safari) используйте
MouseEvent.buttons
- для Safari используйте
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 поднимает свою игру, это должно стать проще.
следующий фрагмент кода попытается выполнить функцию "doStuff" через 2 секунды после события mouseDown в документе.тело. Если пользователь поднимет кнопку, произойдет событие 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); }
Я знаю, что это старый пост, но я думал, что отслеживание кнопки мыши с помощью мыши вверх/вниз чувствовал себя немного неуклюжим, поэтому я нашел альтернативу, которая может обратиться к некоторым.
<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>
: активный селектор обрабатывает щелчок мыши намного лучше, чем мышь вверх/вниз, вам просто нужен способ чтения этого состояния в событии onmousemove. Для этого мне нужно было обмануть и полагаться на то, что курсор по умолчанию является "auto" , и я просто меняю его на" default", что и выбирает auto по умолчанию.
вы можете использовать что-либо в объекте, возвращаемом getComputedStyle, который вы можете использовать в качестве флага, не нарушая внешний вид вашей страницы, например, цвет границы.
Я хотел бы установить свой собственный пользовательский стиль в разделе: active, но я не мог заставить это работать. Было бы лучше, если бы это было возможно.
короткий и сладкий
Я не уверен, почему ни один из предыдущих ответов работал для меня, но я придумал это решение в момент прозрения. Он не только работает, но и самый элегантный:
добавить к тегу body:
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, когда мышь находится над $('.элемент'), цвет меняется в зависимости от того, какая кнопка нажата.
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
событие в одном из этих случаев:
- пользователь одновременно нажимает клавишу клавиатуры и кнопку мыши, отпускает кнопку мыши за пределами окна браузера, а затем отпускает ключ.
- пользователь нажимает два кнопки мыши одновременно, релизы одна кнопка мыши, то другой, как за пределами окна браузера.
если вы работаете в сложной странице с существующими обработчиками событий мыши, я бы рекомендовал обрабатывать событие на захват (вместо пузыря). Для этого просто установите 3-й параметр
addEventListener
totrue
.кроме того, вы можете проверить
event.which
чтобы убедиться, что вы обрабатываете фактическое взаимодействие с пользователем, а не события мыши, напримерelem.dispatchEvent(new Event('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);
добавить обработчик в документ (или окно) вместо документа.тело важно б / у это гарантирует, что 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; }
это кросс-браузерная версия отлично работает для меня.
используя jQuery, следующее решение обрабатывает даже "перетащить страницу, а затем освободить дело".
$(document).mousedown(function(e) { mouseDown = true; }).mouseup(function(e) { mouseDown = false; }).mouseleave(function(e) { mouseDown = false; });
Я не знаю, как он обрабатывает несколько кнопок мыши. Если бы был способ запустить щелчок за окном, а затем привести мышь в окно, то это, вероятно, не будет работать должным образом там тоже.