JavaScript: Überprüfen Sie, ob die Maustaste gedrückt ist?

136

Gibt es eine Möglichkeit zu erkennen, ob eine Maustaste derzeit in JavaScript gedrückt ist?

Ich weiß über das "Mousedown" -Ereignis Bescheid, aber das brauche ich nicht. Einige Zeit nach dem Drücken der Maustaste möchte ich feststellen können, ob sie noch gedrückt ist.

Ist das möglich?

TM.
quelle
14
Warum Sie eine Antwort akzeptieren, die Ihre Frage nicht beantwortet. Das Registrieren von Mousedown und Mouseup ist falsch (da Sie Mouseup außerhalb des Browsers ausführen und den Eindruck erwecken können, dass Sie immer noch ziehen). Nach Ihrem Problem zu kommen und diese Seite zu erreichen ist völlig nutzlos
Jack
@ Jack es beantwortet meine Frage. Bitte lesen Sie meine Frage und dann die Antwort. Anscheinend stimmen über 100 andere Menschen darin überein, dass es eine gute Antwort war.
TM.
4
Ja, aber ich, Alfred und andere 8 sagen Ihnen, dass das Verfolgen von Mouseup und Mousedown nicht der richtige Weg ist. Die richtige Antwort sollte die Analyse des Ereignisobjekts im Handler Ihrer Wahl oder die Analyse aller mausbezogenen Ereignisse (wie Ein- / Ausstieg) umfassen, wenn Sie eine zeitgesteuerte Prüfung anstelle einer ereignisgesteuerten Prüfung benötigen.
Jack
Diese Frage wurde vor mehr als 7 Jahren gestellt und beantwortet. Ich erhalte keine Benachrichtigung, wenn neue Antworten vorliegen (aber für Kommentare). Schreiben Sie eine bessere Antwort und die Community wird sie nach oben bewerten :) Viele Informationen werden veraltet und die Dinge ändern sich.
TM.
2
@ TM. Tut mir leid, Nekro, aber ... Nein, diese Informationen werden niemals an die Spitze gelangen. Eine Nicht-Selbstantwort, die einmal akzeptiert wurde, bleibt für immer an der Spitze. "Oh, so viele Leute haben für diesen gestimmt" bedeutet nicht, dass die Antwort gut ist. es bedeutet nur, dass viele Leute es gesehen haben, dachten, es sieht in Ordnung aus und haben die Gegenstimme getroffen, weil es für sie zu funktionieren schien.
Fund Monica Klage

Antworten:

147

In Bezug auf die Lösung von Pax: Es funktioniert nicht, wenn der Benutzer absichtlich oder versehentlich auf mehr als eine Schaltfläche klickt. Frag mich nicht, woher ich das weiß :-(.

Der richtige Code sollte so lauten:

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

Mit dem Test wie folgt:

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

Wenn Sie wissen möchten, welche Taste gedrückt wird, müssen Sie mouseDown zu einer Reihe von Zählern machen und diese separat für separate Tasten zählen:

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

Jetzt können Sie überprüfen, welche Tasten genau gedrückt wurden:

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

Seien Sie jetzt gewarnt, dass der obige Code nur für standardkonforme Browser funktioniert, die Ihnen eine Schaltflächennummer ab 0 übergeben. IE verwendet eine Bitmaske der aktuell gedrückten Tasten:

  • 0 für "nichts wird gedrückt"
  • 1 für links
  • 2 für rechts
  • 4 für Mitte
  • und eine beliebige Kombination von oben, z. B. 5 für links + Mitte

Passen Sie also Ihren Code entsprechend an! Ich lasse es als Übung.

Und denken Sie daran: IE verwendet ein globales Ereignisobjekt mit dem Namen ... "Ereignis".

Übrigens hat der IE eine in Ihrem Fall nützliche Funktion: Wenn andere Browser "Schaltfläche" nur für Maustastenereignisse (onclick, onmousedown und onmouseup) senden, sendet der IE diese auch mit onmousemove. Sie können also auf onmousemove warten, wenn Sie den Tastenstatus kennen müssen, und nach evt.button suchen, sobald Sie ihn erhalten haben - jetzt wissen Sie, welche Maustasten gedrückt wurden:

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

Natürlich bekommst du nichts, wenn sie tot spielt und sich nicht bewegt.

Relevante Links:

Update Nr. 1 : Ich weiß nicht, warum ich den document.body-Code übernommen habe. Es ist besser, Ereignishandler direkt an das Dokument anzuhängen.

Eugene Lazutkin
quelle
1
Nach dem Testen scheint es, dass evt.button beim Entfernen mit IE7 ...
TM
5
Ich denke, dass dies in Chrome nicht funktioniert, da Chrome keine Mouseup-Ereignisse generiert, wenn das ursprüngliche Mousedown auf einer Bildlaufleiste stattgefunden hat. Ein Beispiel aus diesem Chrome / Chromium-Problem . Ihre linke Maustaste wäre also für immer gedrückt, wenn es eine Bildlaufleiste gibt, die jemand verwendet! (In Chrome)
KajMagnus
1
Ich liebe Ihre Lösung, aber was ist, wenn die Maus aus einer anderen Anwendung stammt? Sagen Sie ms word und ziehen Sie Text. Wie werden Sie feststellen, dass die Maus unten ist?
Shadrack B. Orina
6
Ich verstehe nicht, warum Sie die Mousedown-Array-Elemente im zweiten Beispiel erhöhen. Warum ein Zähler für jeden Knopf und kein Bool für jeden Knopf?
Amwinter
2
Dies ist eine sehr beliebte Frage (und Antwort). Ich bin überrascht, dass dies noch nicht geschehen ist, aber Sie müssen die Mausdaten überhaupt nicht speichern. Sie können einfach event.buttonsan einen beliebigen Ereignisauslöser anschließen, den Sie verwenden, ohne externe gespeicherte Variablen. Ich habe eine brandneue Frage gestellt (weil mein Mouseup-Ereignis nicht immer ausgelöst wird und diese Lösung für mich nicht funktioniert) und diese Antwort in etwa 5 Minuten erhalten.
RoboticRenaissance
32

Dies ist eine alte Frage, und die Antworten hier scheinen hauptsächlich dafür zu sprechen, zu verwenden mousedownund mouseupzu verfolgen, ob eine Taste gedrückt wird. Aber wie andere bereits betont haben, mouseupwird es nur ausgelöst, wenn es im Browser ausgeführt wird, was dazu führen kann, dass der Schaltflächenstatus aus den Augen verloren wird.

Allerdings Mouseevent (jetzt) gibt an, welche Tasten sind zur Zeit gedrückt:

  • Für alle modernen Browser (außer Safari) verwenden MouseEvent.buttons
  • Verwenden Sie für Safari MouseEvent.which( buttonswird für Safari nicht definiert). Hinweis: whichVerwendet andere Zahlen als buttonsfür Rechts- und Mittelklicks.

Wenn auf registriert document, mousemovewird Feuer sofort, sobald der Cursor den Browser wieder eintritt, also wenn die Benutzer Mitteilungen außerhalb dann wird der Staat, sobald sie die Maus wieder in aktualisiert werden.

Eine einfache Implementierung könnte folgendermaßen aussehen:

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;

Wenn kompliziertere Szenarien erforderlich sind (verschiedene Schaltflächen / mehrere Schaltflächen / Steuertasten), lesen Sie die MouseEvent-Dokumente. Wenn Safari sein Spiel aufhebt, sollte dies einfacher werden.

Jono Job
quelle
6
Dieser Code prüft, ob NUR die Primärtaste gedrückt wird, und erfordert, dass alle anderen Tasten gedrückt werden. (zB wenn sowohl primär als auch sekundär gedrückt werden, e.buttonswird 1+2=3, so e.buttons === 1wird falsch sein). Wenn Sie überprüfen möchten, ob die primäre Schaltfläche gedrückt ist, sich aber nicht um andere Schaltflächenzustände kümmern, gehen Sie folgendermaßen vor:(e.buttons & 1) === 1
AJ Richardson
Ich habe eine Situation, in der ich erwarte, dass ich während eines Mauswechsels den Schaltflächencode auf "1" setzen sollte, aber "7" erzeugt - alle Arbeiten sind in Chrome ausgeführt. Hat jemand eine Idee?
Vasily Hall
@VasilyHall Wenn man sich die MDN-Dokumente ansieht MouseEvent.buttons, scheint dies zu 7bedeuten, dass die primären, sekundären und zusätzlichen Schaltflächen zusammen gedrückt werden. Ich bin mir nicht sicher, warum dies der Fall sein sollte - verwenden Sie eine erweiterte Maus? Wenn ja, lohnt es sich vielleicht, es mit einem einfachen zu versuchen. Wenn Sie es nur zum Laufen bringen müssen, können Sie eine bitweise Überprüfung verwenden, um sicherzustellen, dass die linke Taste gedrückt wird, und andere ignorieren. z.B. MouseEvent.buttons & 1 === 1.
Jono Job
Vielen Dank, ich habe mein JavaScript in einem speziellen Browser verwendet: dem eingebetteten Chrome (ium?) In der Adobe Illustrator-Anwendung. Ich wette, die Kombination all der verschiedenen Dinge führt irgendwie zu einer 7, obwohl nur eine Taste gedrückt wird . Da dies in meiner Anwendung konsistent ist, überprüfe ich einfach 1 oder 7, um meine Interaktivität zu erleichtern. Ich werde hinzufügen, obwohl ich die Logitech M570 (oder was auch immer) Trackball-Maus verwende, registriert sie die 1 korrekt im normalen Browser, aber die 7 in Illustrator.
Vasily Hall
16

Ich denke, der beste Ansatz besteht darin, den Status der Maustaste wie folgt selbst aufzuzeichnen:

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

und dann später in Ihrem Code:

if (mouseDown == 1) {
    // the mouse is down, do what you have to do.
}
paxdiablo
quelle
+1 und danke. Ich dachte, ich müsste möglicherweise darauf zurückgreifen, aber ich hatte gehofft, dass es eine Funktion gibt, mit der Sie den Status einfach direkt überprüfen können.
TM.
12
Gibt es einen Grund, keinen Booleschen Wert zu verwenden?
Moala
1
@moala Ich denke, Int scheint weniger zu tippen
Johnathan Elmore
12

Die Lösung ist nicht gut. Man könnte das Dokument "mousedown" und dann außerhalb des Browsers "mouseup", und in diesem Fall würde der Browser immer noch denken, dass die Maus unten ist.

Die einzig gute Lösung ist die Verwendung des IE.event-Objekts.

Alfred
quelle
11
Ich sehe, woher Sie kommen, aber eine Lösung zu haben, die nur für den Internet Explorer funktioniert, ist auch keine gute Lösung.
TM.
@alfred In einigen Fällen kann es hilfreich sein zu wissen, ob mousemove aus dem Fenster ist. If (event.target.nodeName.toLowerCase === 'html') down = 0;
BF
6

Ich weiß, dass dies ein alter Beitrag ist, aber ich dachte, dass das Verfolgen der Maustaste mit der Maus nach oben / unten etwas klobig ist, deshalb habe ich eine Alternative gefunden, die einige ansprechen könnte.

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

Der: active-Selektor verarbeitet den Mausklick viel besser als die Maus nach oben / unten. Sie benötigen lediglich eine Möglichkeit, diesen Status im Ereignis onmousemove zu lesen. Dafür musste ich schummeln und mich darauf verlassen, dass der Standardcursor "auto" ist und ich ändere ihn einfach auf "default", was standardmäßig automatisch ausgewählt wird.

Sie können alles in dem Objekt verwenden, das von getComputedStyle zurückgegeben wird und das Sie als Flag verwenden können, ohne das Erscheinungsbild Ihrer Seite zu beeinträchtigen, z. B. Rahmenfarbe.

Ich hätte gerne meinen eigenen benutzerdefinierten Stil im Abschnitt: active festgelegt, aber ich konnte das nicht zum Laufen bringen. Es wäre besser, wenn es möglich wäre.

Martin
quelle
Vielen Dank für das Teilen. Ich habe diese Idee für eine Drag-and-Drop-Styling-Logik verwendet, hatte jedoch ein Problem mit dem Internet Explorer und musste zusätzliche Logik
einbeziehen
4

Das folgende Snippet versucht 2 Sekunden nach dem Auftreten des mouseDown-Ereignisses in document.body, die Funktion "doStuff" auszuführen. Wenn der Benutzer die Schaltfläche anhebt, tritt das mouseUp-Ereignis auf und bricht die verzögerte Ausführung ab.

Ich würde empfehlen, eine Methode für das browserübergreifende Anhängen von Ereignissen zu verwenden. Um das Beispiel zu vereinfachen, wurden die Eigenschaften für Mousedown und Mouseup explizit festgelegt.

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

quelle
Danke, aber das ist nicht ganz das Verhalten, nach dem ich gesucht habe (obwohl ich sehen kann, wie meine Frage anzeigt, dass ich dies versuche).
TM.
3

Kurz und bündig

Ich bin mir nicht sicher, warum keine der vorherigen Antworten für mich funktioniert hat, aber ich habe diese Lösung in einem Eureka-Moment gefunden. Es funktioniert nicht nur, es ist auch am elegantesten:

Zum Body-Tag hinzufügen:

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

Dann testen und ausführen, myfunction()wenn downgleich 1:

onmousemove="if (down==1) myfunction();"
Stanley
quelle
4
du bist neu, also werde ich dir hier ein bisschen helfen. Achten Sie zunächst auf Ihre Grammatik in Ihren Posts - ich habe wahrscheinlich mehr Zeit damit verbracht, sie zu reparieren, als Sie hineingesteckt haben. Zweitens ist Ihre Lösung nur eine andere Version der anderen oben aufgeführten - es ist nichts Neues. Drittens verwendet Ihre Lösung eine Technik, die als "Verwenden von Flags" bezeichnet wird und von Thomas Hansen oben vorgeschlagen wurde. Bitte achten Sie darauf, Ihre Grammatik zu überprüfen und Lösungen nicht zu wiederholen, wenn Sie in älteren Posts posten, ohne eine Erklärung dafür zu geben, warum die anderen Lösungen für Sie nicht funktionierten.
Zachary Kniebel
5
Ich habe jedoch Ihre Lösung
abgestimmt
2

Sie können @Pax und meine Antworten kombinieren, um auch die Dauer zu ermitteln, für die die Maus gedrückt wurde:

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

Dann später:

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

quelle
Das ist keine schlechte Idee, Jake. Müssen Sie Interval () in onmouseup () löschen, bevor Sie Mousedown auf 0 setzen? Ich bin vorsichtig, wenn die Timer-Funktion zwischen dem Setzen auf 0 und dem Stoppen des Timers ausgelöst wird und das Timeout bei 200? Ähnliches gilt für Onmousedown.
Paxdiablo
Die Reihenfolge der clearIntervals wird keinen Unterschied machen, da der aktuelle Ausführungsthread beendet wird, bevor Ereignisse (einschließlich Timer) ausgelöst werden.
Nathaniel Reinhart
2

Sie müssen mit MouseDown und MouseUp umgehen und ein Flag oder etwas setzen, um es "später auf der Straße" zu verfolgen ... :(

Thomas Hansen
quelle
2

Wenn Sie auf einer komplexen Seite mit vorhandenen Maus-Ereignishandlern arbeiten, würde ich empfehlen, das Ereignis bei der Erfassung zu behandeln (anstelle von Bubble). Stellen Sie dazu einfach den 3. Parameter von addEventListenerauf true.

Darüber hinaus möchten Sie möglicherweise überprüfen, ob event.whichSie die tatsächliche Benutzerinteraktion und keine Mausereignisse verarbeiten, z 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);

Fügen Sie den Handler anstelle von document.body zum Dokument (oder Fenster) hinzu. Body ist wichtig, da sichergestellt wird, dass Mouseup-Ereignisse außerhalb des Fensters weiterhin aufgezeichnet werden.

Micah Miller-Eshleman
quelle
1

Verwenden Sie die MouseEvent- API, um die gedrückte Taste zu überprüfen, falls vorhanden:

document.addEventListener('mousedown', (e) => console.log(e.buttons))

Rückgabe :

Eine Zahl, die eine oder mehrere Schaltflächen darstellt. Bei mehr als einer gleichzeitig gedrückten Taste werden die Werte kombiniert (z. B. 3 ist primär + sekundär).

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)
NVRM
quelle
0

Mit jQuery behandelt die folgende Lösung sogar das "Ziehen der Seite, dann Fall freigeben".

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

Ich weiß nicht, wie es mit mehreren Maustasten umgeht. Wenn es eine Möglichkeit gäbe, den Klick außerhalb des Fensters zu starten und dann die Maus in das Fenster zu bringen, würde dies dort wahrscheinlich auch nicht richtig funktionieren.

David
quelle
0

Unterhalb des jQuery-Beispiels ändert sich die Farbe, wenn sich die Maus über $ ('. Element') befindet, je nachdem, welche Maustaste gedrückt wird.

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();
});
Marcin Żurek
quelle
0

Wie gesagt @Jack, wenn mouseupes außerhalb des Browserfensters passiert, sind wir uns dessen nicht bewusst ...

Dieser Code hat (fast) bei mir funktioniert:

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

Leider werde ich die mouseupVeranstaltung in einem dieser Fälle nicht bekommen :

  • Der Benutzer drückt gleichzeitig eine Tastaturtaste und eine Maustaste, lässt die Maustaste außerhalb des Browserfensters los und gibt dann die Taste frei.
  • Der Benutzer drückt zwei Maustasten gleichzeitig, gibt eine Maustaste und dann die andere Taste frei, beide außerhalb des Browserfensters.
Dreadcast
quelle
-1

Nun, Sie können nicht überprüfen, ob es nach dem Ereignis nicht funktioniert, aber Sie können überprüfen, ob es aktiv ist. Wenn es aktiv ist, bedeutet dies, dass es nicht mehr deaktiviert ist: P lol

Der Benutzer drückt also die Taste nach unten (Ereignis onMouseDown) ... und danach prüfen Sie, ob es aktiv ist (onMouseUp). Während es nicht läuft, können Sie tun, was Sie brauchen.

rogeriopvl
quelle
2
Ist onMouseUp nicht auch ein Ereignis? Wie werden Sie die "Eigenschaft" onMouseup überprüfen? Oder wessen Eigentum eher?
Rohit
@Rohit: Sie überprüfen die Eigenschaft nicht, Sie verwalten ein Flag, das anzeigt, dass das Ereignis eingetreten ist ... Die Maustaste ist entweder nach oben oder nach unten gerichtet.
PhiLho
-1
        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;
        }

Diese browserübergreifende Version funktioniert gut für mich.

user2550945
quelle