Есть ли способ определить, находится ли кнопка мыши в данный момент в JavaScript?
Я знаю о событии "mousedown", но это не то, что мне нужно. Через некоторое время после нажатия кнопки мыши я хочу определить, нажата ли она по-прежнему.
Это возможно?
Есть ли способ определить, находится ли кнопка мыши в данный момент в JavaScript?
Я знаю о событии "mousedown", но это не то, что мне нужно. Через некоторое время после нажатия кнопки мыши я хочу определить, нажата ли она по-прежнему.
Это возможно?
Ответы:
Что касается решения 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 и выше. IE использует битовую маску нажатых в данный момент кнопок:
Так что скорректируйте свой код соответственно! Я оставляю это как упражнение.
И помните: 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. Будет лучше прикрепить обработчики событий непосредственно к документу.
event.buttonsк любому используемому вами триггеру события без внешних сохраненных переменных. Я задал совершенно новый вопрос (потому что мое мышиное событие не всегда срабатывает, поэтому это решение не работает для меня) и получил этот ответ за 5 минут.
Это старый вопрос, и ответы здесь, по-видимому, в основном требуют использования mousedownи mouseupотслеживания нажатия кнопки. Но, как уже отмечали другие,mouseup срабатывает только при выполнении в браузере, что может привести к потере контроля над состоянием кнопки.
Однако MouseEvent (сейчас) указывает, какие кнопки нажимаются в данный момент:
MouseEvent.buttonsMouseEvent.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 отменяет свою игру, это должно стать проще.
e.buttonsбудет 1+2=3, поэтому e.buttons === 1будет ложным). Если вы хотите проверить, не нажата ли основная кнопка, но не заботитесь о других состояниях кнопок, сделайте следующее:(e.buttons & 1) === 1
MouseEvent.buttons, кажется, это 7означает, что он думает, что кнопки Primary, Secondary и Auxilary все нажаты вместе. Я не уверен, почему это так - вы используете продвинутую мышь? Если так, возможно, стоит попробовать базовый. Если вам нужно только запустить его, вы можете использовать побитовую проверку, чтобы убедиться, что левая кнопка нажата, и игнорировать любые другие. например. MouseEvent.buttons & 1 === 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.
}
решение не хорошее. можно «навести» на документ, затем «навести курсор мыши» за пределы браузера, и в этом случае браузер все еще будет думать, что мышь не работает.
Единственное хорошее решение - использовать объект 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. Для этого мне нужно было обмануть и полагаться на то, что курсором по умолчанию является «авто», и я просто изменяю его на «по умолчанию», то есть то, что автоматически выбирает по умолчанию.
В объекте вы можете использовать все, что возвращает getComputedStyle, которое вы можете использовать в качестве флага, не нарушая внешний вид вашей страницы, например, border-color.
Мне бы хотелось установить свой собственный стиль в разделе: 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 и установить какой-нибудь флаг или что-то такое, чтобы отслеживать его «позже в будущем» ... :(
Если вы работаете на сложной странице с существующими обработчиками событий мыши, я бы порекомендовал обрабатывать событие при захвате (вместо пузыря). Для этого просто установите 3-й параметр addEventListenerв true.
Кроме того, вы можете проверить, 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);
Добавьте обработчик к документу (или окну) вместо document.body важно, потому что он гарантирует, что события mouseup за пределами окна по-прежнему записываются.
Используя API MouseEvent , чтобы проверить нажатую кнопку, если есть:
document.addEventListener('mousedown', (e) => console.log(e.buttons))
Число, представляющее одну или несколько кнопок. Если одновременно нажимается более одной кнопки, значения объединяются (например, 3 является первичным + вторичным).
0 : No button or un-initialized 1 : Primary button (usually the left button) 2 : Secondary button (usually the right button) 4 : Auxilary button (usually the mouse wheel button or middle button) 8 : 4th button (typically the "Browser Back" button) 16 : 5th button (typically the "Browser Forward" button)
Используя 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событие в одном из этих случаев:Ну, вы не можете проверить, не горит ли он после события, но вы можете проверить, горит ли он ... Если он горит ... это означает, что больше не гаснет: 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;
}
эта кросс-браузерная версия отлично работает для меня.