Pregunta

¿Hay alguna forma de detectar si un botón del mouse está actualmente desactivado en JavaScript?

Sé sobre el " mousedown " evento, pero eso no es lo que necesito. Algún tiempo DESPUÉS de presionar el botón del mouse, quiero poder detectar si todavía está presionado.

¿Es esto posible?

¿Fue útil?

Solución

Respecto a la solución de Pax: no funciona si el usuario hace clic en más de un botón de manera intencional o accidental. No me preguntes cómo sé :-(.

El código correcto debería ser así:

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

Con la prueba como esta:

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

Si desea saber qué botón se presiona, prepárese para hacer que mouseDown sea una matriz de contadores y contarlos por separado para botones separados:

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

Ahora puede verificar qué botones se presionaron exactamente:

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

Ahora tenga en cuenta que el código anterior funcionaría solo para navegadores que cumplan con los estándares y que le pasen un número de botón a partir de 0. IE utiliza una máscara de bits de los botones presionados actualmente:

  • 0 para " no se presiona nada "
  • 1 para la izquierda
  • 2 por derecho
  • 4 para el medio
  • y cualquier combinación de las anteriores, por ejemplo, 5 para izquierda + media

¡Así que ajusta tu código en consecuencia! Lo dejo como ejercicio.

Y recuerde: IE usa un objeto de evento global llamado & # 8230; " evento " ;.

Por cierto, IE tiene una función útil en su caso: cuando otros navegadores envían el botón """ solo para eventos de botón del mouse (onclick, onmousedown y onmouseup), IE también lo envía con onmousemove. Por lo tanto, puede comenzar a escuchar onmousemove cuando necesite conocer el estado del botón y verificar el botón evt. Tan pronto como lo tenga & # 8212; ahora ya sabe qué botones del mouse se presionaron:

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

Por supuesto, no obtienes nada si ella se hace la muerta y no se mueve.

Enlaces relevantes:

Actualización n. ° 1 : no sé por qué transfirí el código del documento. Será mejor adjuntar controladores de eventos directamente al documento.

Otros consejos

Esta es una vieja pregunta, y las respuestas aquí parecen recomendar principalmente el uso de mousedown y mouseup para realizar un seguimiento de si se presiona un botón. Pero como otros han señalado, mouseup solo se activará cuando se realice dentro del navegador, lo que puede conducir a perder la noción del estado del botón.

Sin embargo, MouseEvent (ahora) indica qué botones son actualmente empujado:

  • Para todos los navegadores modernos (excepto Safari) use MouseEvent.buttons
  • Para Safari, use MouseEvent.which ( botones no estará definido para Safari) Nota: que usa diferentes números de botones para los clics derecho y medio.

Cuando se registre en document , mousemove se activará inmediatamente tan pronto como el cursor vuelva a entrar en el navegador, por lo que si el usuario se libera, el estado se actualizará tan pronto vuelven a colocar el mouse dentro.

Una implementación simple podría verse así:

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;

Si se requieren escenarios más complicados (botones diferentes / botones múltiples / teclas de control), consulte los documentos de MouseEvent. Cuando / si Safari levanta su juego, esto debería ser más fácil.

Creo que el mejor enfoque para esto es mantener su propio registro del estado del botón del mouse, de la siguiente manera:

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

y luego, más adelante en su código:

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

la solución no es buena. uno podría "mousedown" en el documento, luego "mouseup" fuera del navegador, y en este caso el navegador aún estaría pensando que el mouse está caído.

la única buena solución es usar el objeto IE.event.

Sé que esta es una publicación antigua, pero pensé que el seguimiento del botón del mouse usando el mouse arriba / abajo se sentía un poco torpe, así que encontré una alternativa que puede ser atractiva para algunos.

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

El selector activo maneja el clic del mouse mucho mejor que el mouse arriba / abajo, solo necesita una forma de leer ese estado en el evento onmousemove. Para eso necesitaba hacer trampa y confiar en el hecho de que el cursor predeterminado es "auto". y simplemente lo cambio a "predeterminado", que es lo que selecciona automáticamente de forma predeterminada.

Puede usar cualquier cosa en el objeto que devuelve getComputedStyle que puede usar como indicador sin alterar el aspecto de su página, p. color de borde.

Me hubiera gustado establecer mi propio estilo definido por el usuario en la sección: active, pero no pude lograr que funcione. Sería mejor si fuera posible.

El siguiente fragmento intentará ejecutar el " doStuff " funciona 2 segundos después de que ocurra el evento mouseDown en document.body. Si el usuario levanta el botón, se producirá el evento mouseUp y cancelará la ejecución retrasada.

Aconsejaría usar algún método para adjuntar eventos de navegador cruzado: se configuró explícitamente las propiedades de mousedown y mouseup para simplificar el ejemplo.

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

Corto y dulce

No estoy seguro de por qué ninguna de las respuestas anteriores funcionó para mí, pero se me ocurrió esta solución durante un momento eureka. No solo funciona, sino que también es muy elegante:

Añadir a la etiqueta del cuerpo:

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

Luego pruebe y ejecute myfunction () si down es igual a 1 :

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

Puede combinar @Pax y mis respuestas para obtener también la duración de la inactividad del mouse:

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

Luego más tarde:

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

Necesita manejar MouseDown y MouseUp y establecer alguna bandera o algo para rastrearlo "más adelante" ... :(

Usando jQuery, la siguiente solución maneja incluso el "arrastrar fuera de la página y luego suelta el caso".

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

No sé cómo maneja múltiples botones del mouse. Si hubiera una manera de comenzar el clic fuera de la ventana, luego lleve el mouse a la ventana, entonces probablemente tampoco funcionaría correctamente allí.

Debajo del ejemplo de jQuery, cuando el mouse está sobre $ ('. element'), el color cambia dependiendo del botón del mouse que se presione.

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

Como se dijo @Jack, cuando mouseup ocurre fuera de la ventana del navegador, no nos damos cuenta ...

Este código (casi) funcionó para mí:

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

Desafortunadamente, no obtendré el evento mouseup en uno de esos casos:

  • el usuario presiona simultáneamente una tecla del teclado y un botón del mouse, suelta el botón del mouse fuera de la ventana del navegador y luego suelta la tecla.
  • el usuario presiona dos botones del mouse simultáneamente, suelta un botón del mouse y luego el otro, ambos fuera de la ventana del navegador.

Si está trabajando dentro de una página compleja con controladores de eventos de mouse existentes, le recomiendo manejar el evento en captura (en lugar de burbuja). Para hacer esto, simplemente configure el tercer parámetro de addEventListener en true .

Además, es posible que desee verificar event.which para asegurarse de que está manejando la interacción real del usuario y no los eventos del mouse, p. elem.dispatchEvent (nuevo Evento ('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);

Agregue el controlador al documento (o ventana) en lugar de document.body es importante porque garantiza que los eventos de mouseup fuera de la ventana aún se graben.

Bueno, no puedes comprobar si está inactivo después del evento, pero puedes comprobar si está activo ... Si está activo ... significa que ya no está inactivo: P lol

Entonces el usuario presiona el botón hacia abajo (evento onMouseDown) ... y después de eso, verifica si está activo (onMouseUp). Si bien no está activo, puede hacer lo que necesite.

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

esta versión de navegador cruzado funciona bien para mí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top