web-dev-qa-db-fra.com

Détecter plusieurs touches sur un seul événement de pression de touche dans jQuery

Est-il possible de combiner un mélange de touches pour déclencher un seul événement?

$(document).keyup(function(e){
    if (e.keyCode == 68 && e.keyCode == 69 && e.keyCode == 86) {
        alert('oh hai');
    }
});

Je l'ai essayé en Chrome mais l'événement ne se déclenche pas.

Appelez-moi fou mais j'écris une extension Chrome et je veux pousser D+E+V ensemble pour le forcer à passer en mode développeur caché.

42
remarsh

Si vous voulez détecter que le de, et v les clés étaient toutes en panne en même temps, vous devez regarder à la fois keydown et keyup et garder une carte de celles qui sont en panne. Quand ils sont tous en panne, déclenchez votre événement.

Par exemple: Live copy | source

var map = {68: false, 69: false, 86: false};
$(document).keydown(function(e) {
    if (e.keyCode in map) {
        map[e.keyCode] = true;
        if (map[68] && map[69] && map[86]) {
            // FIRE EVENT
        }
    }
}).keyup(function(e) {
    if (e.keyCode in map) {
        map[e.keyCode] = false;
    }
});

Je suppose que vous ne vous souciez pas de l'ordre dans lequel ils sont enfoncés (car ce serait pénible d'appuyer de manière fiable) tant qu'ils sont tous en même temps à un moment donné.

72
T.J. Crowder

Similaire à Vega ... mais plus simple

var down = {};
$(document).keydown(function(e) {
    down[e.keyCode] = true;
}).keyup(function(e) {
    if (down[68] && down[69] && down[86]) {
        alert('oh hai');
    }
    down[e.keyCode] = false;
});​
18
Parth Thakkar

Peut-être qu'une combinaison de touches plus simple serait plus facile?

Que diriez-vous de quelque chose comme Shift + Alt + D? (Vous ne devriez probablement pas utiliser la touche Contrôle car la plupart des navigateurs interprètent déjà Ctrl + D d'une manière ou d'une autre)

Le code pour ceci serait quelque chose comme ceci:

if(e.shiftKey && e.altKey && e.keyCode == 68)
{
  alert('l33t!');
}
8
gplumb

J'ai une réponse de T.J. Crowder en javascript simple pour quelqu'un qui voudrait éviter Jquery.

//A W S D simultaneously
var map = {65: false, 87: false, 83: false, 68: false};
document.body.addEventListener('keydown', function (e) {
    var e = e || event; //to deal with old IE
    if (e.keyCode in map) {
        map[e.keyCode] = true;
        if (map[65] && map[87]) {
            console.log('up left');
        }else if (map[83] && map[68]) {
            console.log('down right');
        }else if (map[87] && map[68]) {
            console.log('up right');
        }else if (map[83] && map[65]) {
            console.log('down left');
        }
    }
});
document.body.addEventListener('keyup', function (e) {
    if (e.keyCode in map) {
        map[e.keyCode] = false;
    }
});
3
Smelino

Vous devrez capturer les trois événements clés séparément et déclencher votre action uniquement après le troisième.

var keys = {
        d: { code: 100, pressed: false, next: 'e' },
        e: { code: 101, pressed: false, next: 'v' },
        v: { code: 118, pressed: false, next: 'd' }
    },
    nextKey = 'd';

$(document).keypress(function(e) {
    if (e.keyCode === keys[nextKey].code) {
        keys[nextKey].pressed = true;
        nextKey = keys[nextKey].next;
    } else {
        keys.d.pressed = false;
        keys.e.pressed = false;
        keys.v.pressed = false;
        nextKey = 'd';
    }

    if (keys.d.pressed && keys.e.pressed && keys.v.pressed) {
        alert('Entering dev mode...');
    }
});​

Il y a bien sûr plusieurs façons de procéder. Cet exemple ne vous oblige pas à maintenir les touches enfoncées simultanément, juste que vous les tapez dans l'ordre: dev.

Si vous l'avez utilisé, vous souhaiterez peut-être l'augmenter pour effacer les indicateurs pressed après un certain intervalle de temps.

Voici un exemple de travail .


Avertissement: je me rends compte que la question d'origine disait que les touches devaient être "pressées ensemble". Ceci est juste une alternative car d'autres répondeurs ont déjà fourni des solutions suffisantes pour les touches pressées ensemble.

1
FishBasketGordo

J'ai essayé les trois meilleures réponses (à ce jour), et aucune d'entre elles n'a fonctionné pour moi. Ils n'ont pas réinitialisé les clés .

S'il fallait 3 touches pour déclencher le script, après l'avoir tiré une fois - appuyer sur l'une des 3 touches le déclencherait à nouveau.

Je viens d'écrire ce script et ça marche très bien. Il utilise Shift + S pour tirer, mais vous pouvez facilement changer cela. Il se réinitialise après avoir appuyé sur la combinaison.

var saveArray = new Array();
saveArray[0] = false;
saveArray[1] = false;

$(document).ready(function(){

    $(document).keydown(function (f){
        if (f.keyCode == 16) {
            saveArray[0] = true;
        }
    });

    $(document).keyup(function (g){
        if(g.which == 16){
            saveArray[0] = false;
        }
    });

    $(document).keydown(function (h){
        if (h.keyCode == 83) {
            saveArray[1] = true;
            if(saveArray[0] == true && saveArray[1] == true){
                saveArray[0] = false;
                saveArray[1] = false;
                keypressSaveFunction();
            }
        }
    });

    $(document).keyup(function (i){
        if (i.which == 83) {
            saveArray[1] = false;
        }
    });
});

    function keypressSaveFunction(){
        alert("You pressed Shift+S");
    }

Violon: http://jsfiddle.net/9m8yswwo/13/

1
Nemo-Omen

Solution un peu plus moderne, profite de fonctions fléchées et paramètres de repos :

const multipleKeypress = (function($document) {
  // Map of keys which are currently down.
  const keymap = {}
  // Update keymap on keydown and keyup events.
  $document.on(
    "keydown keyup"
    // If the key is down, assign true to the corresponding
    // propery of keymap, otherwise assign false.
   ,event => keymap[event.keyCode] = event.type === "keydown"
  )
  // The actual function.
  // Takes listener as the first argument,
  // rest of the arguments are key codes.
  return (listener, ...keys) =>
    $document.keydown(() => {
      // Check if every of the specified keys is down.
      if (keys.every(key => keymap[key]))
        listener(event)
    })
// Pass a jQuery document object to cache it.
}($(document)))

// Example usage:
multipleKeypress(() => console.log("pressed"), 68, 69, 86)

// Automatically focus the snippet result
window.focus()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Try pressing <kbd>d</kbd>, <kbd>e</kbd> and <kbd>v</kbd> at once.</p>
1

si j'ai bien compris: exemple de violon, http://jsfiddle.net/gAtTk/ (regardez votre console js)

ce code vous permettra d'entrer le mot "dev" (et dans cet exemple, à la fin l'événement keyup est supprimé)

(function(seq) {
    var tmp = seq.slice();
    $(document).on("keyup.entersequence", function(e){
        if (!(e.keyCode === tmp.pop())) {
           tmp = seq.slice();
        }
        else {
           console.log(e.keyCode);  
            if (!tmp.length) {
               console.log('end');
               $(document).off("keyup.entersequence");
            }
        }
    });
}([68,69,86].reverse()));
0
fcalderan

Vous devez utiliser les événements keydown et keyup pour gérer plus d'une clé "en même temps".

input.on("keydown", function (e) {
                        if (e.which == 17) {
                            isCtrl = true; // Ctrl
                            return;
                        }

                        /* Ctrl and "c" */
                        if (isCtrl && e.which == 67) {
                            //some code 
                        }
                    }).keyup(function (e) {
                        if (e.which == 17) {
                            isCtrl = false; // no Ctrl
                        }
                    });
0
kapsiR

Utilisez ce code pour déclencher un événement en appuyant plusieurs fois sur la touche + Délai d'expiration après 100 ms pour éviter les erreurs de frappe. Dans cet exemple: si A, Z, E sont pressés dans un délai de 100 ms, l'événement sera déclenché.

var map = {65:false,90:false,69:false}; //Modify keyCodes here
$(document).keydown(function(e){
    console.log(e.keyCode);
    map[e.keyCode] = e.keyCode in map ? true : map[e.keyCode] || false;
    var result = Object.keys(map).filter(function(key){
        return map[key];
    }).length === Object.keys(map).length ? true : false;
    if(result){
        //Your event here
        Object.keys(map).forEach(function(key){
            map[key] = false;
        });
    }
    setTimeout(function(){
        map[e.keyCode] = false;
    },100);
});
0
Yves-Richard HTH