web-dev-qa-db-fra.com

Vérifier si une clé est en panne?

Existe-t-il un moyen de détecter si une clé est actuellement inactive en JavaScript?

Je connais l'événement "keydown", mais ce n'est pas ce dont j'ai besoin. Quelque temps après avoir appuyé sur la touche, je veux pouvoir détecter si elle est toujours enfoncée.

P. S. Le plus gros problème semble être qu'après un certain temps, la clé commence à se répéter, déclenchant des événements tels que les démons. Espérons qu’il n’ya qu’une simple fonction isKeyDown (clé), mais si ce n’est pas le cas, ce problème devra être résolu/résolu.

73
Daniel X Moore

Existe-t-il un moyen de détecter si une clé est actuellement inactive en JavaScript?

Nan. La seule possibilité est de surveiller chaque keyup et keydown et de se souvenir.

après un certain temps, la clé commence à se répéter, déclenchant des événements comme des monstres.

Cela ne devrait pas. Vous aurez certainement la répétition de keypress, et dans de nombreux navigateurs, vous aurez également la répétition de keydown, mais si keyup se répète, c'est un bogue.

Malheureusement, ce n’est pas un bug totalement inouï: sous Linux, Chromium et Firefox (lorsqu’il est exécuté sous GTK +, qui est présent dans des distributions populaires telles que Ubuntu), des séquences répétitives répétées keyup-press-key-keydown qui sont impossibles à distinguer de quelqu'un enfonçant la clé très vite.

55
bobince

En plus d'utiliser les écouteurs keyup et keydown pour suivre quand sa clé est utilisée et sauvegardée, il y a are en fait, certaines propriétés vous indiquent si certaines clés sont en panne.

window.onmousemove = function (e) {
  if (!e) e = window.event;
  if (e.shiftKey) {/*shift is down*/}
  if (e.altKey) {/*alt is down*/}
  if (e.ctrlKey) {/*ctrl is down*/}
  if (e.metaKey) {/*cmd is down*/}
}

Ceux-ci sont disponibles sur tous les objets d'événements générés par le navigateur, tels que ceux de keydown, keyup et keypress, de sorte que vous n'avez pas à utiliser mousemove.

J'ai essayé de générer mes propres objets d'événement avec document.createEvent('KeyboardEvent') et document.createEvent('KeyboardEvent') et de rechercher e.shiftKey et autres, mais je n'ai pas eu de chance.

J'utilise Chrome 17 sur Mac

109
Devin G Rhode

Ma solution:

var keys = {};
window.onkeyup = function(e) { keys[e.keyCode] = false; }
window.onkeydown = function(e) { keys[e.keyCode] = true; }

Je peux maintenant vérifier si une touche est enfoncée ailleurs dans le script en cochant

keys["code of the key"]

Si c'est vrai, la touche est enfoncée.

32
Robert

Je ne crois pas qu'il y ait quoi que ce soit comme une fonction isKeyDown, mais vous pourriez écrire la vôtre.

Fondamentalement, créez un tableau dont la longueur correspond au nombre de clés que vous souhaitez surveiller. Puis, à l'aide des événements documents/pages/contrôles keyUp et keyDown, mettez à jour le tableau avec l'état de cette clé.

Ensuite, écrivez une fonction qui vérifie si une certaine touche est enfoncée et renvoie une valeur booléenne.

var keyEnum = { W_Key:0, A_Key:1, S_Key:2, D_Key:3 };
var keyArray = new Array(4);

function onKeyDown()
{
    // Detect which key was pressed
    if( key == 'w' )
        keyArray[keyEnum.W_Key] = true;
    // Repeat for each key you care about...
}

function onKeyUp()
{
    // Detect which key was released
    if( key == 'w' )
        keyArray[keyEnum.W_Key] = false;
    // Repeat for each key you care about...
}

function isKeyDown(key)
{
    return keyArray[key];
}

Cela devrait accomplir ce que vous voulez.

11
FallenAvatar
/*
Tracks what keys are currently down on the keyboard
*/

function keyboard_module(onUpdate){
    var kb = {};
    var unicode_mapping = {};
    document.onkeydown = function(e){
        var unicode=e.charCode? e.charCode : e.keyCode
        var key = getKey(unicode);
        kb[key] = true;
        if(onUpdate){
            onUpdate(kb);
        }
    }

    document.onkeyup = function(e){
        var unicode=e.charCode? e.charCode : e.keyCode
        var key = getKey(unicode);
        delete kb[key];
        if(onUpdate){
            onUpdate(kb);
        }
    }

    function getKey(unicode){
        if(unicode_mapping[unicode]){
            var key = unicode_mapping[unicode];
        }else{
            var key= unicode_mapping[unicode] = String.fromCharCode(unicode);
        }
        return key;
    }
    return kb;
}

function testing(kb){
    console.log('These are the down keys', kb);
}


var keyboard = keyboard_module(testing);

....
//somewhere else in the code
if(keyboard['K']){/*do something special */}
1
RobKohr

D'autres personnes ont déjà posé ce genre de question (bien que je ne voie pas de dupes évidentes ici pour le moment).

Je pense que la réponse est que l'événement keydown (et son jumeau keyup) sont toutes les informations que vous obtenez. La répétition est connectée assez fermement au système d'exploitation et un programme d'application n'a pas vraiment l'occasion d'interroger le BIOS pour connaître l'état réel de la clé.

Ce que vous pouvez faire, et peut-être devoir faire si vous avez besoin pour que cela fonctionne, est de supprimer la clé par programme. Essentiellement, vous pouvez évaluer keydown et keyup vous-même, mais ignorer un événement keyup s'il se produit trop rapidement après le dernier keydown... ou si vous devez essentiellement différer votre réponse à keyup suffisamment longtemps pour qu'il n'y ait pas d'autre événement keydown 0,25 seconde de keyup.

Cela impliquerait l'utilisation d'une activité de minuterie et l'enregistrement des millisecondes des événements précédents. Je ne peux pas dire que c'est une solution très attrayante, mais ...

1
Carl Smotricz

Le code suivant correspond à ce que j'utilise:

var altKeyDownCount = 0;
window.onkeydown = function (e) {
    if (!e) e = window.event;
    if (e.altKey) {
        altKeyDownCount++;
        if (30 < altKeyDownCount) {
            $('.key').removeClass('hidden');
            altKeyDownCount = 0;
        }
        return false;
    }
}

window.onkeyup = function (e) {
    if (!e) e = window.event;
    altKeyDownCount = 0;
    $('.key').addClass('hidden');
}

Lorsque l'utilisateur maintient la touche Alt enfoncée pendant un certain temps (environ 2 secondes), un groupe d'étiquettes (classe = 'clé masquée') apparaît. Lorsque vous relâchez la touche Alt, les étiquettes disparaissent. jQuery et Bootstrap sont tous deux utilisés.

1
Johnny

Regardez this answer et utilisez onkeyup et onkeydown. Ici est une information plus spécifique sur ces événements.

0
Claudiu

J'ai scanné les réponses ci-dessus et l'approche keydown/keyup proposée ne fonctionne que dans des circonstances spéciales. Si l'utilisateur alt-tabs ou utilise un geste de clé pour ouvrir une nouvelle fenêtre ou un nouvel onglet de navigateur, alors une keydown sera enregistrée, ce qui est correct, car il est alors impossible de déterminer si la clé est quelque chose de l'application Web. surveillance, ou est un navigateur standard ou un raccourci du système d'exploitation. Revenons à la page du navigateur, mais nous penserons toujours que la clé est enfoncée, bien qu’elle ait été publiée entre-temps. Ou une touche est simplement maintenue enfoncée pendant que l'utilisateur bascule vers un autre onglet ou une autre application avec la souris, puis le publie en dehors de notre page.

Les touches de modification (Shift etc.) peuvent être contrôlées via mousemove etc. en supposant qu'au moins une interaction de la souris est attendue lors de la tabulation arrière, ce qui est fréquemment le cas.

Pour la plupart des autres clés (à l'exception des modificateurs, Tab, Delete, mais incluant Space, Enter), la surveillance keypress fonctionnerait pour la plupart des applications; une clé maintenue continuerait à être activée. Cependant, il y a une certaine latence dans la réinitialisation de la clé, en raison de la périodicité de l'activation de keypress. En gros, si keypress ne continue pas à tirer, il est possible d’écarter la plupart des clés. Ceci, combiné avec les modificateurs, est assez hermétique, bien que je n’ai pas exploré quoi faire avec Tab et Backspace.

Je suis sûr qu'il y a une bibliothèque qui résume cette faiblesse du DOM, ou peut-être qu'un changement de norme DOM s'en est occupé, car c'est une question un peu ancienne.

0
Robert Monfera

Nous nous sommes retrouvés ici pour vérifier s’il y avait déjà quelque chose d’intégré dans le navigateur, mais il semble qu’il n’en ait pas Voici ma solution (très similaire à la réponse de Robert):

"use strict";

let is_key_down = (() => {
    let state = {};

    window.addEventListener('keyup', (e) => state[e.key] = false);
    window.addEventListener('keydown', (e) => state[e.key] = true);

    return (key) => state.hasOwnProperty(key) && state[key] || false;
})();

Vous pouvez ensuite vérifier si une touche est enfoncée avec is_key_down('ArrowLeft').

0
antonagestam

Je sais que cette question est très ancienne. Cependant, il existe une bibliothèque JavaScript très légère (~ .5Kb) qui "corrige" le déclenchement incohérent des gestionnaires d’événements clavier lors de l’utilisation de l’API DOM.

La bibliothèque est Keydrown .

Voici l'exemple de code opérationnel qui a bien fonctionné pour mes besoins en modifiant simplement la clé sur laquelle définir l'auditeur:

kd.P.down(function () {
  console.log('The "P" key is being held down!');
});

kd.P.up(function () {
  console.clear();
});

// This update loop is the heartbeat of Keydrown
kd.run(function () {
  kd.tick();
});

J'ai incorporé Keydrown dans mon JavaScript côté client pour une animation de pause appropriée dans un jeu Red Light Green Light que j'écris. Vous pouvez voir le jeu entier ici . (Remarque: si vous lisez ceci à l'avenir, le jeu devrait être complet et lisible :-D!)

J'espère que ça aide.

0
buildpax