Wie kann man mithilfe von JavaScript erkennen, ob mehrere Tasten gleichzeitig gedrückt werden?

173

Ich versuche eine JavaScript-Spiel-Engine zu entwickeln und bin auf dieses Problem gestoßen:

  • Wenn ich drücke SPACE, springt der Charakter.
  • Wenn ich drücke , bewegt sich der Charakter nach rechts.

Das Problem ist, dass wenn ich nach rechts drücke und dann die Leertaste drücke, der Charakter springt und sich dann nicht mehr bewegt.

Ich benutze die keydownFunktion, um die Taste zu drücken. Wie kann ich überprüfen, ob mehrere Tasten gleichzeitig gedrückt wurden?

XCS
quelle
3
Hier ist eine Demo einer Webseite, die automatisch eine Liste aller gedrückten Tasten druckt: stackoverflow.com/a/13651016/975097
Anderson Green

Antworten:

327

Hinweis: keyCode ist jetzt veraltet.

Die Erkennung mehrerer Tastenanschläge ist einfach, wenn Sie das Konzept verstehen

So mache ich das:

var map = {}; // You could also use an array
onkeydown = onkeyup = function(e){
    e = e || event; // to deal with IE
    map[e.keyCode] = e.type == 'keydown';
    /* insert conditional here */
}

Dieser Code ist sehr einfach: Da der Computer jeweils nur einen Tastendruck durchläuft, wird ein Array erstellt, um mehrere Schlüssel zu verfolgen. Das Array kann dann verwendet werden, um gleichzeitig nach einem oder mehreren Schlüsseln zu suchen.

Nehmen wir zur Erklärung an, Sie drücken Aund B, jedes löst ein keydownEreignis aus, das map[e.keyCode]auf den Wert von gesetzt e.type == keydownist und entweder als wahr oder falsch ausgewertet wird . Jetzt sind beide map[65]und map[66]eingestellt auf true. Wenn Sie loslassen A, wird das keyupEreignis ausgelöst, wodurch dieselbe Logik das entgegengesetzte Ergebnis für map[65](A) ermittelt, das jetzt falsch ist , aber da map[66](B) immer noch "down" ist (es hat kein Keyup-Ereignis ausgelöst). es bleibt wahr .

Das mapArray sieht bei beiden Ereignissen folgendermaßen aus:

// keydown A 
// keydown B
[
    65:true,
    66:true
]
// keyup A
// keydown B
[
    65:false,
    66:true
]

Sie können jetzt zwei Dinge tun:

A) Ein Schlüsselprotokollierer ( Beispiel ) kann als Referenz für später erstellt werden, wenn Sie schnell einen oder mehrere Schlüsselcodes herausfinden möchten. Angenommen, Sie haben ein HTML-Element definiert und mit der Variablen darauf verwiesen element.

element.innerHTML = '';
var i, l = map.length;
for(i = 0; i < l; i ++){
    if(map[i]){
        element.innerHTML += '<hr>' + i;
    }
}

Hinweis: Sie können ein Element leicht anhand seines idAttributs erfassen.

<div id="element"></div>

Dadurch wird ein HTML-Element erstellt, auf das in Javascript leicht verwiesen werden kann element

alert(element); // [Object HTMLDivElement]

Sie müssen es nicht einmal benutzen document.getElementById()oder $()greifen. Aus Kompatibilitätsgründen sollten Sie jedoch jQuery's verwenden$() allgemein empfohlen.

Stellen Sie einfach sicher, dass das Skript- Tag hinter dem HTML-Text steht. Optimierungstipp : Die meisten namhaften Websites setzen das Skript- Tag zur Optimierung nach dem Body-Tag. Dies liegt daran, dass das Skript-Tag das Laden weiterer Elemente blockiert, bis das Herunterladen des Skripts abgeschlossen ist. Wenn Sie es vor den Inhalt stellen, kann der Inhalt zuvor geladen werden.

B (hier liegt Ihr Interesse) Sie können nach einem oder mehreren Schlüsseln gleichzeitig suchen /*insert conditional here*/. Nehmen Sie dieses Beispiel:

if(map[17] && map[16] && map[65]){ // CTRL+SHIFT+A
    alert('Control Shift A');
}else if(map[17] && map[16] && map[66]){ // CTRL+SHIFT+B
    alert('Control Shift B');
}else if(map[17] && map[16] && map[67]){ // CTRL+SHIFT+C
    alert('Control Shift C');
}

Bearbeiten : Das ist nicht das am besten lesbare Snippet. Die Lesbarkeit ist wichtig, daher können Sie so etwas ausprobieren, um die Augen zu schonen:

function test_key(selkey){
    var alias = {
        "ctrl":  17,
        "shift": 16,
        "A":     65,
        /* ... */
    };

    return key[selkey] || key[alias[selkey]];
}

function test_keys(){
    var keylist = arguments;

    for(var i = 0; i < keylist.length; i++)
        if(!test_key(keylist[i]))
            return false;

    return true;
}

Verwendung:

test_keys(13, 16, 65)
test_keys('ctrl', 'shift', 'A')
test_key(65)
test_key('A')

Ist das besser?

if(test_keys('ctrl', 'shift')){
    if(test_key('A')){
        alert('Control Shift A');
    } else if(test_key('B')){
        alert('Control Shift B');
    } else if(test_key('C')){
        alert('Control Shift C');
    }
}

(Ende der Bearbeitung)


In diesem Beispiel wird überprüft CtrlShiftA, CtrlShiftBundCtrlShiftC

So einfach ist das :)

Anmerkungen

KeyCodes im Auge behalten

In der Regel empfiehlt es sich, Code zu dokumentieren, insbesondere Schlüsselcodes (wie // CTRL+ENTER), damit Sie sich daran erinnern können, was sie waren.

Sie sollten die Schlüsselcodes auch in derselben Reihenfolge wie die Dokumentation CTRL+ENTER => map[17] && map[13]einfügen ( , NICHT map[13] && map[17]). Auf diese Weise werden Sie nie verwirrt, wenn Sie zurückgehen und den Code bearbeiten müssen.

Ein Gotcha mit If-else-Ketten

Wenn Sie nach Combos mit unterschiedlichen Beträgen (wie CtrlShiftAltEnterund CtrlEnter) suchen, setzen Sie kleinere Combos nach größeren Combos. Andernfalls überschreiben die kleineren Combos die größeren Combos, wenn sie ähnlich genug sind. Beispiel:

// Correct:
if(map[17] && map[16] && map[13]){ // CTRL+SHIFT+ENTER
    alert('Whoa, mr. power user');
}else if(map[17] && map[13]){ // CTRL+ENTER
    alert('You found me');
}else if(map[13]){ // ENTER
    alert('You pressed Enter. You win the prize!')
}

// Incorrect:
if(map[17] && map[13]){ // CTRL+ENTER
    alert('You found me');
}else if(map[17] && map[16] && map[13]){ // CTRL+SHIFT+ENTER
    alert('Whoa, mr. power user');
}else if(map[13]){ // ENTER
    alert('You pressed Enter. You win the prize!');
}
// What will go wrong: When trying to do CTRL+SHIFT+ENTER, it will
// detect CTRL+ENTER first, and override CTRL+SHIFT+ENTER.
// Removing the else's is not a proper solution, either
// as it will cause it to alert BOTH "Mr. Power user" AND "You Found Me"

Gotcha: "Diese Tastenkombination wird weiterhin aktiviert, obwohl ich die Tasten nicht drücke."

Wenn Sie mit Warnungen oder anderen Elementen arbeiten, die den Fokus aus dem Hauptfenster übernehmen, möchten Sie möglicherweise map = []das Array zurücksetzen, nachdem die Bedingung erfüllt ist. Dies liegt daran, dass einige Dinge, wie z. B. alert()den Fokus vom Hauptfenster wegnehmen und dazu führen, dass das 'keyup'-Ereignis nicht ausgelöst wird. Beispielsweise:

if(map[17] && map[13]){ // CTRL+ENTER
    alert('Oh noes, a bug!');
}
// When you Press any key after executing this, it will alert again, even though you 
// are clearly NOT pressing CTRL+ENTER
// The fix would look like this:

if(map[17] && map[13]){ // CTRL+ENTER
    alert('Take that, bug!');
    map = {};
}
// The bug no longer happens since the array is cleared

Gotcha: Browser-Standardeinstellungen

Hier ist eine nervige Sache, die ich mit der enthaltenen Lösung gefunden habe:

Problem: Da der Browser normalerweise Standardaktionen für Tastenkombinationen ausführt (z. B. CtrlDdas Lesezeichenfenster CtrlShiftCaktivieren oder Skynote auf maxthon aktivieren), möchten Sie möglicherweise auch return falsenachher hinzufügen map = [], damit Benutzer Ihrer Website nicht frustriert werden, wenn die "Datei duplizieren" Wenn diese Funktion CtrlDaktiviert ist, wird stattdessen die Seite mit einem Lesezeichen versehen.

if(map[17] && map[68]){ // CTRL+D
    alert('The bookmark window didn\'t pop up!');
    map = {};
    return false;
}

Ohne würdereturn false das Lesezeichenfenster zum Entsetzen des Benutzers auftauchen.

Die return-Anweisung (neu)

Okay, Sie möchten die Funktion an diesem Punkt nicht immer beenden. Deshalb ist die event.preventDefault()Funktion da. Es wird ein internes Flag gesetzt, das den Interpreter anweist, dem Browser nicht zu erlauben, seine Standardaktion auszuführen. Danach wird die Ausführung der Funktion fortgesetzt (während returndie Funktion sofort beendet wird).

Verstehen Sie diese Unterscheidung, bevor Sie sich für return falseoder entscheidene.preventDefault()

event.keyCode ist veraltet

Benutzer SeanVieira wies in den Kommentaren darauf hin, dass event.keyCodeveraltet ist.

Dort gab er eine ausgezeichnete Alternative : event.key, die eine Zeichenfolgendarstellung der gedrückten Taste zurückgibt, wie "a"für Aoder "Shift"für Shift.

Ich ging voran und kochte ein Werkzeug, um diese Saiten zu untersuchen.

element.onevent vs. element.addEventListener

Mit registrierte Handler addEventListenerkönnen gestapelt werden und werden in der Reihenfolge der Registrierung aufgerufen, während die .oneventdirekte Einstellung ziemlich aggressiv ist und alles überschreibt, was Sie zuvor hatten.

document.body.onkeydown = function(ev){
    // do some stuff
    ev.preventDefault(); // cancels default actions
    return false; // cancels this function as well as default actions
}

document.body.addEventListener("keydown", function(ev){
    // do some stuff
    ev.preventDefault() // cancels default actions
    return false; // cancels this function only
});

Die .oneventEigenschaft scheint alles und das Verhalten von zu überschreiben ev.preventDefault()und return false;kann ziemlich unvorhersehbar sein.

In beiden Fällen addEventlistenerscheinen über registrierte Handler einfacher zu schreiben und zu begründen zu sein.

Es gibt auch attachEvent("onevent", callback)eine nicht standardmäßige Implementierung von Internet Explorer, die jedoch nicht mehr als veraltet ist und sich nicht einmal auf JavaScript bezieht (es handelt sich um eine esoterische Sprache namens JScript ). Es wäre in Ihrem besten Interesse, polyglotten Code so weit wie möglich zu vermeiden.

Eine Helferklasse

Um Verwirrung / Beschwerden zu beheben, habe ich eine "Klasse" geschrieben, die diese Abstraktion ausführt ( Pastebin-Link ):

function Input(el){
    var parent = el,
        map = {},
        intervals = {};
    
    function ev_kdown(ev)
    {
        map[ev.key] = true;
        ev.preventDefault();
        return;
    }
    
    function ev_kup(ev)
    {
        map[ev.key] = false;
        ev.preventDefault();
        return;
    }
    
    function key_down(key)
    {
        return map[key];
    }

    function keys_down_array(array)
    {
        for(var i = 0; i < array.length; i++)
            if(!key_down(array[i]))
                return false;

        return true;
    }
    
    function keys_down_arguments()
    {
        return keys_down_array(Array.from(arguments));
    }
    
    function clear()
    {
        map = {};
    }
    
    function watch_loop(keylist, callback)
    {
        return function(){
            if(keys_down_array(keylist))
                callback();
        }
    }

    function watch(name, callback)
    {
        var keylist = Array.from(arguments).splice(2);

        intervals[name] = setInterval(watch_loop(keylist, callback), 1000/24);
    }

    function unwatch(name)
    {
        clearInterval(intervals[name]);
        delete intervals[name];
    }

    function detach()
    {
        parent.removeEventListener("keydown", ev_kdown);
        parent.removeEventListener("keyup", ev_kup);
    }
    
    function attach()
    {
        parent.addEventListener("keydown", ev_kdown);
        parent.addEventListener("keyup", ev_kup);
    }
    
    function Input()
    {
        attach();

        return {
            key_down: key_down,
            keys_down: keys_down_arguments,
            watch: watch,
            unwatch: unwatch,
            clear: clear,
            detach: detach
        };
    }
    
    return Input();
}

Diese Klasse macht nicht alles und behandelt nicht jeden denkbaren Anwendungsfall. Ich bin kein Bibliothekar. Für den allgemeinen interaktiven Gebrauch sollte dies jedoch in Ordnung sein.

Um diese Klasse zu verwenden, erstellen Sie eine Instanz und zeigen Sie auf das Element, dem Sie Tastatureingaben zuordnen möchten:

var input_txt = Input(document.getElementById("txt"));

input_txt.watch("print_5", function(){
    txt.value += "FIVE ";
}, "Control", "5");

Dadurch wird dem Element mit einen neuen Eingabe-Listener hinzugefügt #txt angehängt (nehmen wir an, es handelt sich um einen Textbereich), und ein Überwachungspunkt für die Tastenkombination festgelegt Ctrl+5. Wenn beide Ctrlund nicht 5verfügbar sind, wird die von Ihnen übergebene Rückruffunktion (in diesem Fall eine Funktion, die "FIVE "den Textbereich erweitert) aufgerufen. Der Rückruf ist mit dem Namen verknüpft. print_5Um ihn zu entfernen, verwenden Sie einfach:

input_txt.unwatch("print_5");

So lösen Sie sich input_txtvom txtElement:

input_txt.detach();

Auf diese Weise kann die Garbage Collection das Objekt ( input_txt) aufnehmen, falls es weggeworfen wird, und Sie haben keinen alten Zombie-Ereignis-Listener mehr übrig.

Aus Gründen der Gründlichkeit finden Sie hier eine kurze Referenz zur API der Klasse, die im C / Java-Stil dargestellt wird, damit Sie wissen, was sie zurückgeben und welche Argumente sie erwarten.

Boolean  key_down (String key);

Gibt zurück, truewenn keydown ist, andernfalls false.

Boolean  keys_down (String key1, String key2, ...);

Gibt zurück, truewenn alle Schlüssel gedrückt key1 .. keyNsind, andernfalls false.

void     watch (String name, Function callback, String key1, String key2, ...);

Erstellt einen "Überwachungspunkt", bei dem durch Drücken von "Alle" keyNder Rückruf ausgelöst wird

void     unwatch (String name);

Entfernt den Überwachungspunkt über seinen Namen

void     clear (void);

Löscht den Cache "Schlüssel runter". Entspricht map = {}oben

void     detach (void);

Trennt das ev_kdownund die ev_kupListener vom übergeordneten Element, sodass die Instanz sicher entfernt werden kann

Update 2017-12-02 Als Antwort auf eine Anfrage, dies in github zu veröffentlichen, habe ich eine Übersicht erstellt .

Update 2018-07-21 Ich habe eine Weile mit deklarativem Programmieren gespielt und dieser Weg ist jetzt mein persönlicher Favorit: Geige , Pastebin

Im Allgemeinen funktioniert es mit den Fällen, die Sie realistisch möchten (Strg, Alt, Umschalt), aber wenn Sie beispielsweise drücken müssen, a+w , wäre es nicht allzu schwierig, die Ansätze zu einem zu "kombinieren" Multi-Key-Lookup.


Ich hoffe diese gründlich erklärte Antwort Mini-Blog war hilfreich :)

Braden Best
quelle
Ich habe gerade ein großes Update für diese Antwort gemacht! Das Keylogger-Beispiel ist kohärenter, ich habe die Formatierung aktualisiert, damit der Abschnitt "Notizen" leichter zu lesen ist, und ich habe return falsepreventDefault()
Braden Best
Was ist, wenn Sie eine Taste mit fokussiertem Dokument drücken / halten, dann auf das URL-Feld klicken und dann die Taste loslassen? keyup wird nie ausgelöst, aber der Schlüssel ist aktiv, was dazu führt, dass die Liste falsch ist. Auch umgekehrt: Drücken / Halten der Taste im URL-Feld, Keydown wird nie ausgelöst, dann Fokus auf Dokument und der Keydown-Status ist nicht auf der Liste. Grundsätzlich können Sie sich des Schlüsselstatus nie sicher sein, wenn das Dokument wieder den Fokus erhält.
user3015682
3
NB: keyCodeist veraltet - wenn Sie zu wechseln, erhalten keySie die tatsächliche Zeichendarstellung des Schlüssels, was sehr hilfreich sein kann.
Sean Vieira
1
@ SeanVieira Andererseits kannst du auch in C ein paar seltsame Sachen machen. Wussten Sie zum Beispiel, dass dies myString[5]dasselbe ist wie 5[myString]und dass Sie nicht einmal eine Kompilierungswarnung erhalten (auch nicht mit -Wall -pedantic)? Es ist , weil die pointer[offset]Notation der Zeiger nimmt, fügt den Offset und dereferenziert dann das Ergebnis, so dass myString[5]das gleiche wie *(myString + 5).
Braden Best
1
@inorganik beziehen Sie sich auf die Hilfsklasse? Können Gists wie Repos verwendet werden? Es wäre mühsam, ein ganzes Repo für einen winzigen Codeausschnitt zu erstellen. Klar, ich mache einen Kern. Ich werde für heute Nacht schießen. Midnight Mountain Time -ish
Braden Best
30

Sie sollten das Keydown- Ereignis verwenden, um die gedrückten Tasten zu verfolgen, und Sie sollten die Tastenkombination verwenden Ereignis verwenden, um zu verfolgen, wann die Tasten losgelassen werden.

Siehe dieses Beispiel: http://jsfiddle.net/vor0nwe/mkHsU/

(Update: Ich reproduziere den Code hier, falls jsfiddle.net ausfällt :) Der HTML:

<ul id="log">
    <li>List of keys:</li>
</ul>

... und das Javascript (mit jQuery):

var log = $('#log')[0],
    pressedKeys = [];

$(document.body).keydown(function (evt) {
    var li = pressedKeys[evt.keyCode];
    if (!li) {
        li = log.appendChild(document.createElement('li'));
        pressedKeys[evt.keyCode] = li;
    }
    $(li).text('Down: ' + evt.keyCode);
    $(li).removeClass('key-up');
});

$(document.body).keyup(function (evt) {
    var li = pressedKeys[evt.keyCode];
    if (!li) {
       li = log.appendChild(document.createElement('li'));
    }
    $(li).text('Up: ' + evt.keyCode);
    $(li).addClass('key-up');
});

In diesem Beispiel verwende ich ein Array, um zu verfolgen, welche Tasten gedrückt werden. In einer realen Anwendung möchten Sie vielleichtdelete jedes Element, sobald der zugehörige Schlüssel freigegeben wurde.

Beachten Sie, dass ich in diesem Beispiel zwar jQuery verwendet habe, um mir die Arbeit zu erleichtern, das Konzept jedoch genauso gut funktioniert, wenn Sie in "rohem" Javascript arbeiten.

Martijn
quelle
Aber wie ich dachte, gibt es einen Fehler. Wenn Sie eine Taste gedrückt halten, wechseln Sie zu einer anderen Registerkarte (oder verlieren Sie den Fokus), während Sie die Taste gedrückt halten, wenn Sie sich erneut auf das Skript konzentrieren. Dies zeigt an, dass die Taste gedrückt wird, auch wenn dies nicht der Fall ist. : D
XCS
3
@Cristy: Dann können Sie auch einen onblurEreignishandler hinzufügen , der alle gedrückten Tasten aus dem Array entfernt. Sobald Sie den Fokus verloren haben, ist es sinnvoll, alle Tasten erneut drücken zu müssen. Leider gibt es kein JS-Äquivalent zu GetKeyboardState.
Martijn
1
Problem beim Einfügen auf einem Mac (Chrome). Es wird erfolgreich Keydown 91 (Befehl), Keydown 86 (v) abgerufen, aber dann wird nur die 91 eingegeben, wobei 86 nicht aktiviert wird. Liste der Tasten: Up: 91, Down: 86. Dies scheint nur zu passieren, wenn die Befehlstaste als zweites losgelassen wird. Wenn ich sie zuerst loslasse, wird die Tastenfolge bei beiden korrekt registriert.
James Alday
2
Wenn Sie drei oder mehr Tasten gleichzeitig drücken, werden keine weiteren Tasten mehr erkannt, bis Sie eine anheben. (Getestet mit Firefox 22)
Qvcool
1
@ JamesAlday Gleiches Problem. Es betrifft anscheinend nur den Meta (OS) -Schlüssel auf Macs. Siehe Ausgabe Nr. 3 hier: bitspushedaround.com/…
Don McCurdy
20
document.onkeydown = keydown; 

function keydown (evt) { 

    if (!evt) evt = event; 

    if (evt.ctrlKey && evt.altKey && evt.keyCode === 115) {

        alert("CTRL+ALT+F4"); 

    } else if (evt.shiftKey && evt.keyCode === 9) { 

        alert("Shift+TAB");

    } 

}
Eduardo La Hoz Miranda
quelle
1
Das war alles was ich wollte, beste Antwort
Randall Coding
7

Ich habe diesen Weg benutzt (musste überprüfen, wo Umschalt + Strg gedrückt wird):

// create some object to save all pressed keys
var keys = {
    shift: false,
    ctrl: false
};

$(document.body).keydown(function(event) {
// save status of the button 'pressed' == 'true'
    if (event.keyCode == 16) {
        keys["shift"] = true;
    } else if (event.keyCode == 17) {
        keys["ctrl"] = true;
    }
    if (keys["shift"] && keys["ctrl"]) {
        $("#convert").trigger("click"); // or do anything else
    }
});

$(document.body).keyup(function(event) {
    // reset status of the button 'released' == 'false'
    if (event.keyCode == 16) {
        keys["shift"] = false;
    } else if (event.keyCode == 17) {
        keys["ctrl"] = false;
    }
});
Array
quelle
5

für wer braucht vollständigen Beispielcode. Rechts + Links hinzugefügt

var keyPressed = {};
document.addEventListener('keydown', function(e) {

   keyPressed[e.key + e.location] = true;

    if(keyPressed.Shift1 == true && keyPressed.Control1 == true){
        // Left shift+CONTROL pressed!
        keyPressed = {}; // reset key map
    }
    if(keyPressed.Shift2 == true && keyPressed.Control2 == true){
        // Right shift+CONTROL pressed!
        keyPressed = {};
    }

}, false);

document.addEventListener('keyup', function(e) {
   keyPressed[e.key + e.location] = false;

   keyPressed = {};
}, false);
Reza Ramezanpour
quelle
3

Lassen Sie den Keydown sogar mehrere Funktionen aufrufen, wobei jede Funktion nach einer bestimmten Taste sucht und entsprechend reagiert.

document.keydown = function (key) {

    checkKey("x");
    checkKey("y");
};
AnonymousGast
quelle
2

Ich würde versuchen, einen keypress EventHandler hinzuzufügen keydown. Z.B:

window.onkeydown = function() {
    // evaluate key and call respective handler
    window.onkeypress = function() {
       // evaluate key and call respective handler
    }
}

window.onkeyup = function() {
    window.onkeypress = void(0) ;
}

Dies soll nur ein Muster veranschaulichen; Ich werde hier nicht ins Detail gehen (insbesondere nicht auf die browserspezifische Level2 + EventRegistrierung).

Bitte zurückschicken, ob dies hilft oder nicht.

FK82
quelle
1
Dies würde nicht funktionieren: keypress nicht Trigger auf eine Menge von Tasten , dass keydown und keyUp tun Trigger. Außerdem lösen nicht alle Browser wiederholt Keydown-Ereignisse aus.
Martijn
Quirksmode sagt, dass Sie falsch liegen: quirksmode.org/dom/events/keys.html . Aber ich werde das nicht argumentieren, da ich meinen Vorschlag nicht getestet habe.
FK82
Zitat von dieser Seite aus : „Wenn der Benutzer spezielle Tasten wie die Pfeiltasten, sollte der Browser nicht keypress Ereignisse ausgelöst“ . Bei den Wiederholungen werden Opera und Konqueror als nicht korrekt aufgeführt.
Martijn
2

Wenn eine der gedrückten Tasten Alt / Strg / Umschalt ist, können Sie diese Methode verwenden:

document.body.addEventListener('keydown', keysDown(actions) );

function actions() {
   // do stuff here
}

// simultaneous pressing Alt + R
function keysDown (cb) {
  return function (zEvent) {
    if (zEvent.altKey &&  zEvent.code === "KeyR" ) {
      return cb()
    }
  }
}
Michael Lester
quelle
2
    $(document).ready(function () {
        // using ascii 17 for ctrl, 18 for alt and 83 for "S"
        // ctr+alt+S
        var map = { 17: false, 18: false, 83: false };
        $(document).keyup(function (e) {
            if (e.keyCode in map) {
                map[e.keyCode] = true;
                if (map[17] && map[18] && map[83]) {
                    // Write your own code here, what  you want to do
                    map[17] = false;
                    map[18] = false;
                    map[83] = false;
                }
            }
            else {
                // if u press any other key apart from that "map" will reset.
                map[17] = false;
                map[18] = false;
                map[83] = false;
            }
        });

    });
Prosun Chakraborty
quelle
Vielen Dank für Ihren Beitrag. Bitte versuchen Sie nicht nur die Postleitzahl, sondern fügen Sie eine Erklärung hinzu.
Tim Rutter
2

Dies ist keine universelle Methode, aber in einigen Fällen nützlich. Es ist nützlich für Kombinationen wie CTRL+ somethingoder Shift+ somethingoder CTRL+ Shift+ somethingusw.

Beispiel: Wenn Sie drucken möchten , eine Seite mit CTRL+ Pgedrückt, ersten Schlüssel wird immer CTRLgefolgt von P. Gleiches gilt für CTRL+ S, CTRL+ Uund andere Kombinationen.

document.addEventListener('keydown',function(e){
      
    //SHIFT + something
    if(e.shiftKey){
        switch(e.code){

            case 'KeyS':
                console.log('Shift + S');
                break;

        }
    }

    //CTRL + SHIFT + something
    if(e.ctrlKey && e.shiftKey){
        switch(e.code){

            case 'KeyS':
                console.log('CTRL + Shift + S');
                break;

        }
    }

});

Jakub Muda
quelle
1
case 65: //A
jp = 1;
setTimeout("jp = 0;", 100);

if(pj > 0) {
ABFunction();
pj = 0;
}
break;

case 66: //B
pj = 1;
setTimeout("pj = 0;", 100);

if(jp > 0) {
ABFunction();
jp = 0;
}
break;

Nicht der beste Weg, ich weiß.

Anonym
quelle
-1
Easiest, and most Effective Method

//check key press
    function loop(){
        //>>key<< can be any string representing a letter eg: "a", "b", "ctrl",
        if(map[*key*]==true){
         //do something
        }
        //multiple keys
        if(map["x"]==true&&map["ctrl"]==true){
         console.log("x, and ctrl are being held down together")
        }
    }

//>>>variable which will hold all key information<<
    var map={}

//Key Event Listeners
    window.addEventListener("keydown", btnd, true);
    window.addEventListener("keyup", btnu, true);

    //Handle button down
      function btnd(e) {
      map[e.key] = true;
      }

    //Handle Button up
      function btnu(e) {
      map[e.key] = false;
      }

//>>>If you want to see the state of every Key on the Keybaord<<<
    setInterval(() => {
                for (var x in map) {
                    log += "|" + x + "=" + map[x];
                }
                console.log(log);
                log = "";
            }, 300);
Flugzauberer
quelle