L'event "keydown" s'active plusieurs fois

Résolu/Fermé
Hibou-Propulseur Messages postés 3 Date d'inscription lundi 26 juillet 2021 Statut Membre Dernière intervention 22 août 2021 - Modifié le 26 juil. 2021 à 18:25
kaneagle Messages postés 85144 Date d'inscription mercredi 27 mai 2009 Statut Modérateur Dernière intervention 20 avril 2024 - 22 août 2021 à 14:25
Bonjour !
Je travaille le déplacement dans un petit moteur 3D, et j'utilise pour cela les touches du clavier.
En gros, quand on appuie sur "z", on avance jusqu'à ce qu'on relève la touche.
J'utilise donc les événements
keyup
et
keydown
avec un écouteur d'événement.
Tout marche très bien (keydown lance un "setInterval", et keyup le supprime). Seulement si on appuie un peu trop longtemps, keyup se lance plusieurs fois et il n'y a plus assez de keyup pour supprimer les boucles... Pourquoi ? Comment changer ça ?
Merci !

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>3D</title>
  </head>
  <body onload="initialiser();">
 <p id="x">x:</p>
 <p id="y">y:</p>
 <p id="z">z:</p>
    <script src="jsTEST.js"></script>
  </body>
</html>


function refresh(){
 pX.innerHTML = "x: "+xC;
 pY.innerHTML = "y: "+yC;
 pZ.innerHTML = "z: "+zC;
}

function initialiser(){
 console.log("---creation des touches d'écoute---");
 var dict = {
  90 : function(){//Z
   zC += vitesse/nbDePasParSec;
  },
  81 : function(){//Q
   xC -= vitesse/nbDePasParSec;
  },
  83 : function(){//S
   zC -= vitesse/nbDePasParSec;
  },
  68 : function(){//D
   xC += vitesse/nbDePasParSec;
  },
  32 : function(){//SPACEBAR
   yC += vitesse/nbDePasParSec;
  },
  16 : function(){//shift
   yC -= vitesse/nbDePasParSec;
  }
 };
 var dictIntervalles = {};
 document.addEventListener("keydown", function(e) {
  console.log("keydown");
  for(var k in dict) {
   if (e.keyCode == k) {
    console.log("touche n°: "+k+" appuyée");
    function modif(){
     dict[k]();
     refresh();
    }
    modif();
    dictIntervalles[k] = setInterval(modif,1000/nbDePasParSec);// tant que la touche est appuyée on avance régulièrement
   }
  }
 });
 document.addEventListener("keyup", function(e) {
  for(var k in dictIntervalles) {
   if (e.keyCode == k) {
    console.log("touche n°: "+k+" relevée");
    clearInterval(dictIntervalles[k]);
    delete dictIntervalles[k];
   }
  }
 });
 console.log("touches d'écoute créées");
}
var xC=0, yC=0, zC=0;
var pX = document.getElementById("x");
var pY = document.getElementById("y");
var pZ = document.getElementById("z");
var vitesse = 1;// distance faite à chaque seconde
var nbDePasParSec = 6;// fluidité du mouvement
refresh();

2 réponses

Hibou-Propulseur Messages postés 3 Date d'inscription lundi 26 juillet 2021 Statut Membre Dernière intervention 22 août 2021
Modifié le 26 juil. 2021 à 18:34
Ok j'ai trouvé une réponse... (https://javascript.info/keyboard-events)

Auto-repeat
If a key is being pressed for a long enough time, it starts to “auto-repeat”: the keydown triggers again and again, and then when it’s released we finally get keyup. So it’s kind of normal to have many keydown and a single keyup.

For events triggered by auto-repeat, the event object has event.repeat property set to true.

donc ça donne :
document.addEventListener("keydown", function(e) {
  console.log("keydown");
  for(var k in dict) {
   if (e.keyCode == k) {
    if (e.repeat != true){// petite modif ici !
     console.log("touche n°: "+k+" appuyée");
     function modif(){
      dict[k]();
      refresh();
     }
     modif();
     dictIntervalles[k] = setInterval(modif,1000/nbDePasParSec);
    }
   }
  }
 });


EDIT: Comment on fait pour clore ce sujet ?
0
kaneagle Messages postés 85144 Date d'inscription mercredi 27 mai 2009 Statut Modérateur Dernière intervention 20 avril 2024 14 278
22 août 2021 à 14:25
Bonjour,

Comment on fait pour clore ce sujet ? 


Regarde ceci -->> Marquer un fil de discussion comme étant résolu

0