Domanda

Esiste un modo per rilevare se un pulsante del mouse è attualmente inattivo in JavaScript?

Conosco il "mousedown" evento, ma non è quello di cui ho bisogno. Qualche volta dopo aver premuto il pulsante del mouse, voglio essere in grado di rilevare se è ancora premuto.

È possibile?

È stato utile?

Soluzione

Per quanto riguarda la soluzione di Pax: non funziona se l'utente fa clic intenzionalmente o accidentalmente su più di un pulsante. Non chiedermi come lo so :-(.

Il codice corretto dovrebbe essere così:

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

Con il test in questo modo:

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

Se vuoi sapere quale pulsante viene premuto, preparati a rendere mouseDown un array di contatori e contali separatamente per pulsanti separati:

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

Ora puoi controllare quali pulsanti sono stati premuti esattamente:

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

Ora tieni presente che il codice sopra funzionerebbe solo per i browser conformi allo standard che ti passano un numero di pulsante a partire da 0 in su. IE utilizza una maschera di bit dei pulsanti attualmente premuti:

  • 0 per " nulla viene premuto "
  • 1 a sinistra
  • 2 per destra
  • 4 per il mezzo
  • e qualsiasi combinazione di cui sopra, ad esempio 5 per left + middle

Quindi regola il tuo codice di conseguenza! Lo lascio come un esercizio.

E ricorda: IE utilizza un oggetto evento globale chiamato & # 8230; & Quot; evento ".

Per inciso IE ha una funzione utile nel tuo caso: quando altri browser inviano il pulsante " " solo per gli eventi del pulsante del mouse (onclick, onmousedown e onmouseup), IE lo invia anche con onmousemove. Quindi puoi iniziare ad ascoltare onmousemove quando devi conoscere lo stato del pulsante e controllare l'evt.button non appena lo ottieni & # 8212; ora sai quali pulsanti del mouse sono stati premuti:

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

Ovviamente non otterrai nulla se lei gioca morta e non si muove.

Link rilevanti:

Aggiornamento n. 1 : non so perché ho riportato il documento in stile document.body-style. Sarà meglio allegare i gestori di eventi direttamente al documento.

Altri suggerimenti

Questa è una vecchia domanda, e le risposte qui sembrano sostenere principalmente l'uso di mousedown e mouseup per tenere traccia del fatto che un pulsante sia premuto. Ma come altri hanno sottolineato, mouseup si attiverà solo se eseguito all'interno del browser, il che può portare a perdere la traccia dello stato del pulsante.

Tuttavia, MouseEvent (ora) indica quali pulsanti sono attualmente spinto:

  • Per tutti i browser moderni (tranne Safari) utilizzare MouseEvent.buttons
  • Per Safari, utilizza MouseEvent.which (i pulsanti non saranno definiti per Safari) Nota: che utilizza numeri diversi dai pulsanti per i clic destro e centrale.

Quando registrato su document , mousemove si attiverà immediatamente non appena il cursore rientrerà nel browser, quindi se l'utente rilascia all'esterno, lo stato verrà aggiornato non appena rientrano con il mouse.

Una semplice implementazione potrebbe apparire come:

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;

Se sono richiesti scenari più complicati (pulsanti diversi / pulsanti multipli / tasti di controllo), consulta i documenti MouseEvent. Quando / se Safari alza il suo gioco, questo dovrebbe essere più facile.

Penso che l'approccio migliore a questo sia quello di tenere traccia dello stato del pulsante del mouse, come segue:

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

e successivamente, nel tuo codice:

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

la soluzione non è buona. si potrebbe "mousedown" sul documento, quindi " mouseup " al di fuori del browser, e in questo caso il browser continuerebbe a pensare che il mouse non sia attivo.

l'unica buona soluzione è usare l'oggetto IE.event.

So che questo è un vecchio post, ma ho pensato che il tracciamento del pulsante del mouse usando il mouse su / giù fosse un po 'goffo, quindi ho trovato un'alternativa che potrebbe piacere ad alcuni.

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

Il selettore: active gestisce il clic del mouse molto meglio del mouse su / giù, hai solo bisogno di un modo per leggere quello stato nell'evento onmousemove. Per questo avevo bisogno di imbrogliare e basarmi sul fatto che il cursore predefinito è "auto". e lo cambio semplicemente in " default " ;, che è ciò che auto seleziona automaticamente.

Puoi usare qualsiasi cosa nell'oggetto che viene restituito da getComputedStyle che puoi usare come flag senza stravolgere l'aspetto della tua pagina, ad es. border-color.

Mi sarebbe piaciuto impostare il mio stile definito dall'utente nella sezione: active, ma non riuscivo a farlo funzionare. Sarebbe meglio se fosse possibile.

Il frammento seguente tenterà di eseguire " doStuff " funzione 2 secondi dopo che si verifica l'evento mouseDown in document.body. Se l'utente alza il pulsante, si verifica l'evento mouseUp e annulla l'esecuzione ritardata.

Consiglio di utilizzare un metodo per l'allegato di eventi cross-browser: l'impostazione delle proprietà mousedown e mouseup è stata esplicitamente eseguita per semplificare l'esempio.

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

Breve e dolce

Non sono sicuro del motivo per cui nessuna delle risposte precedenti ha funzionato per me, ma ho trovato questa soluzione durante un momento di eureka. Non solo funziona, ma è anche molto elegante:

Aggiungi al tag body:

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

Quindi prova ed esegui myfunction () se down è uguale a 1 :

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

Puoi combinare @Pax e le mie risposte per ottenere anche la durata in cui il mouse è inattivo per:

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

Quindi:

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

Devi gestire MouseDown e MouseUp e impostare qualche flag o qualcosa per seguirlo " in seguito lungo la strada " ... :(

Usando jQuery, la seguente soluzione gestisce anche il " trascina fuori dalla pagina quindi rilascia la custodia " ;.

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

Non so come gestisce più pulsanti del mouse. Se ci fosse un modo per avviare il clic fuori dalla finestra, quindi portare il mouse nella finestra, probabilmente anche questo non funzionerebbe correttamente lì.

Sotto l'esempio di jQuery, quando il mouse è sopra $ ('.elemento'), il colore cambia a seconda del pulsante del mouse premuto.

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

Come detto @Jack, quando mouseup avviene al di fuori della finestra del browser, non ne siamo a conoscenza ...

Questo codice (quasi) ha funzionato per me:

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

Purtroppo, in uno di questi casi non riceverò l'evento mouseup :

  • l'utente preme contemporaneamente un tasto della tastiera e un pulsante del mouse, rilascia il pulsante del mouse all'esterno della finestra del browser, quindi rilascia il tasto.
  • l'utente preme contemporaneamente due pulsanti del mouse, rilascia un pulsante del mouse e l'altro, entrambi al di fuori della finestra del browser.

Se lavori all'interno di una pagina complessa con gestori di eventi del mouse esistenti, ti consiglio di gestire l'evento su cattura (anziché bolla). Per fare ciò, basta impostare il terzo parametro di addEventListener su true .

Inoltre, potresti voler controllare event.which per assicurarti di gestire l'interazione dell'utente reale e non gli eventi del mouse, ad es. elem.dispatchEvent (nuovo 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);

Aggiungi il gestore al documento (o alla finestra) invece di document.body è importante in b / c, assicura che gli eventi del mouse fuori dalla finestra siano ancora registrati.

Beh, non puoi controllare se è inattivo dopo l'evento, ma puoi controllare se è attivo ... Se è attivo .. significa che non è più inattivo: P lol

Quindi l'utente preme il pulsante in basso (evento onMouseDown) ... e successivamente, controlla se è attivo (onMouseUp). Anche se non funziona, puoi fare quello che ti serve.

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

questa versione per browser diversi funziona bene per me.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top