Mouseout ne se déclenche pas...

...quand la souris est retirée trop vite de la zone

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour ! :)

Je suis en train d'apprendre le javascript et pour m'entraîner, je m'amuse à coder des défis mathématiques. Le premier que j'ai réalisé se trouve sur cette page, mais j'ai un petit problème que je n'arrive pas à régler.

Dans la liste des nombres qui s'affiche quand on rentre un nombre, j'ai ajouté sur chaque ligne un effet mouseover pour que la multiplication dont le nombre est le résultat s'affiche. Je voudrais que quand la souris quitte la ligne, la multiplication disparaisse et le résultat réapparaisse. Seulement actuellement quand la souris est retirée trop brutalement de la zone, le "mouseout" ne se déclenche pas et la ligne reste bloquée sur l'écriture en multiplication.

Est-ce un problème classique ? Je n'ai rien trouvé à ce sujet.

Voici le code complet de la page, le mouse over/out est géré par la fonction "dynamique()" :

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<!DOCTYPE html>
<html lang="fr">
  <head>
      <meta charset="utf-8" />
        <link rel="stylesheet" href="css/style.css" />
      <title>Défi mathématique</title>
  </head>

  <body>

      <div style="width:49%; border:0px solid black; float:left; min-width: 510px;">

          <center> <!-- Titre et description rapide -->
              <h1>Multiplications de chiffres</h1>
              <h2>Défi mathématique</h2>
              <p style="max-width:700px; font-style:italic;">
                  Partant d'un nombre entier, on calcule le produit de ses chiffres. On répète ce procédé avec le nouveau nombre obtenu, jusqu'à tomber sur un nombre d'un seul chiffre.<br /><strong>Saurez-vous trouver un nombre produisant le plus grand nombre d'étapes possible ?</strong>
              </p>
          </center>
      
          <center> <!-- Formulaire d'entrée du nombre -->
              <div style="height:70px; vertical align:middle;">
                  <input id="nombre" type="text" value="Entrez un nombre" size=15 style="width:500px; height:50px; font-size:40px; color:rgb(200,200,200); border: solid 2px rgb(0,100,200); margin:5px; vertical-align: middle; padding-left:10px;" onFocus="focusNombre()" onBlur="unFocusNombre()" onKeyPress="if (event.keyCode == 13) actu()"; />
              </div>
              <button onclick="actu()" style="width:500px; height:50px; border:2px solid rgb(0,100,200); background-color:rgb(50,130,205); margin:5px; font-size:30px; color:white;" >Calculer</button>
          </center>
          
          <center> <!-- Affichage des calculs -->
              <p id="etapes"> 
              </p>
          </center>
      
      </div>
  
      <div style="width:49%; border:0px solid black; float:left; padding-top:25px;">
          <!-- Description détaillée de l'énigme -->
      </div>
  
  
  <script>
  
      function actu() { // fonction qui écrit les lignes de calcul en fonction du nombre indiqué dans le champ "nombre"
          n = parseInt(document.getElementById('nombre').value, 10);
          if (n>999999999999999 || n<0) { // vérifie que le nombre n'est pas trop grand pour JS
              alert("Veuillez entrer un nombre entier positif de moins de 15 chiffres.");
              } else {
                  Etapes = document.getElementById('etapes');
                  Etapes.innerHTML = ""+n+"<br />";
                  compteurLignes = 0;
                  window.setTimeout(function() {
                      ecrireLigneSuivante(n)
                  }, 300);
              }
      }
      
      function ecrireLigneSuivante(nombre) { //fonction itérée qui écrit les unes après les autres les multiplications
          n = nombre;
          resultat = "";
          if (n>9) {
                  multi = multiChiffres(n);
                  Etapes.innerHTML += "<div class='ligneetape' style='padding:5px; margin:2px;'><span class='nombrefactorise' style='display:none;'>"+multi[1]+"</span><span class='nombreentier'>"+multi[0]+"</span></div>",
                  compteurLignes++;
                  window.setTimeout(function() {
                      ecrireLigneSuivante(multi[0])
                  }, 300);
                  }
                  else {
                  Etapes.innerHTML += "<span id='lignefinetape'>"+compteurLignes+" étapes</span>";
                  dynamique();
                  }
          }

          
  
      function multiChiffres(number) {  //fonction de calcul du produit des chiffres et de la chaîne de caractères de la multiplication
              var resultat        = 1,
                  n               = number,
                  multiplication  = "",
                  initial         = true;
              while (n>0) {
                  chiffre = n%10;
                  resultat = resultat*chiffre;
                  n = (n-chiffre)/10;
                  if (initial) {
                      initial = false;
                      } else {
                      multiplication = "×"+multiplication;
                      }
                  multiplication = chiffre+multiplication;
              }
              return [resultat, multiplication];
      }
  
      function dynamique() { //fait apparaître la multiplication lorsqu'on survole l'une des lignes
          var divetapes = document.getElementById('etapes');
          var lignesetapes = divetapes.getElementsByTagName('div');

          for (var i = 0, c = lignesetapes.length ; i < c ; i++) {
              
              lignesetapes[i].addEventListener('mouseover', function(e) {
                  e = e || window.event; // Compatibilité IE
                  var relatedTarget = e.relatedTarget || e.fromElement; // Idem

                  while (relatedTarget != e.target && relatedTarget.nodeName != 'BODY' && relatedTarget != document) {
                      relatedTarget = relatedTarget.parentNode;
                  }

                  if (relatedTarget != e.target) {
                      e.target.firstChild.setAttribute('style','display: inline; color:rgb(100,100,100);');
                      e.target.lastChild.setAttribute('style','display: none;');
                  }
              }, false);
              
              
              document.addEventListener('mouseout', function(e) {
                  e = e || window.event; // Compatibilité IE
                  var relatedTarget = e.relatedTarget || e.toElement; // Idem

                  while (relatedTarget != e.target && relatedTarget.nodeName != 'BODY' && relatedTarget != document) {
                      relatedTarget = relatedTarget.parentNode;
                  }

                  if (relatedTarget != e.target) {
                      e.target.firstChild.setAttribute('style','display: none;');
                      e.target.lastChild.setAttribute('style','display: inline;');
                  }
              }, false);
          }
      }
      
      
      function focusNombre() {
          document.getElementById("nombre").style.border = "solid 3px rgb(0,100,200)";
          document.getElementById("nombre").style.color = "rgb(100,100,100)";
          if (document.getElementById("nombre").value=="Entrez un nombre")
          document.getElementById("nombre").value="";
      }

      function unFocusNombre() {
          document.getElementById("nombre").style.border = "solid 1px rgb(0,100,200)";
          document.getElementById("nombre").style.color = "rgb(150,150,150)";
          if (document.getElementById("nombre").value=="") {
              document.getElementById("nombre").value="Entrez un nombre";
              document.getElementById("nombre").style.color = "rgb(200,200,200)";
              }
      }
      
    </script>
  
  </body>
</html>

D'une manière générale, si vous avez d'autres remarques à me faire sur mon code, je suis preneur de tous les bons conseils !

Merci pour votre aide :)

L'enseignement est le meilleur moyen d'apprendre ; en communiquant nos connaissances nous continuons à découvrir et à apprendre. (Ernő Rubik)

+1 -0
Staff

Je pense qu'il faut faire les choses dans le monde inverse :

  • si c'est la zone de saisie qui gagne le focus alors on laisse écrire
  • si c'est une autre zone, alors on fait évaluer la saisie.

Je te conseille ausi de stocker le résultat des getElementById("nombre") dans une variable afin que JS n'ait pas tout le temps à recalculer l'élément auquel cela correspond.

+0 -0
Auteur du sujet

Merci pour ta réponse.

Oui, tu as raison, j'ai mis le getElementById("nombre") dans une variable.

Par contre, je ne comprends pas bien ta première remarque. Actuellement, ce ne sont pas les fonctions focus ou unfocus qui lancent le calcul, mais le bouton "Calculer" ou la touche Entrée. Mes fonctions focusNombre() et unFocusNombre() n'ont actuellement qu'un rôle esthétique, elles changent le CSS. Je ne vois pas pourquoi évaluer la zone de saisie dès qu'elle perd le focus ?

L'enseignement est le meilleur moyen d'apprendre ; en communiquant nos connaissances nous continuons à découvrir et à apprendre. (Ernő Rubik)

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte