J'essaie de créer un jeu de multiplication simple en utilisant du pur Javascript. Lorsque je clique sur le bouton Démarrer, il appelle une fonction timeCalc(). La fonction timeCalc déclare un nom de variable fullTime avec la valeur 7 et définit l'intervalle et après chaque seconde fullTime diminue de 1. lorsqu'il diminue à 1, il définit la valeur fullTime à 7.

Si je clique plusieurs fois sur le bouton de démarrage, le temps complet diminue si rapidement et de manière désordonnée, même si j'ai fait clearInterval() au début. Je veux diminuer le fullTime de 7 de manière normale même si je clique dessus plusieurs fois. que se passe-t-il en coulisses ?

Voici mon extrait de code. Merci.

const timeContainer = document.querySelector('.math__time');
const startBtn = document.querySelector('.math__start');

function timeCalc() {
  clearInterval(timeLeft);

  let fullTime = 7;
  timeContainer.textContent = fullTime;

  var timeLeft = setInterval(function() {
    fullTime--;
    timeContainer.textContent = fullTime;

    if (fullTime === 1) {
      fullTime = 7;
    }
  },1000);
}


startBtn.addEventListener('click', timeCalc);
*,
*:before,
*:after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.math {
  background: gray;
  font-family: verdana, sans-serif;
}

.math__calc {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translateY(-50%) translateX(-50%);
}

.math__num {
  margin: 15px;
  color: #fff;
  font-size: 30px;
  padding-left: 100px;
}

.math__num--wrapper {
  position: relative;
}

.math__time {
  padding: 10px;
  background: black;
  color: #fff;
  position: absolute;
  right: 20px;
  top: 20px;
  border: #fff 2px solid;
}
 

.math__start {
  position: absolute;
  left: 20px;
  top: 20px;
  border: 2px solid #fff;
  background: #333;
  color: #fff;
  padding: 10px;
}

.math__multiply--symbol {
  position: absolute;
  bottom: -10px;
  left: 10px;
  font-size: 30px;
}
<!DOCTYPE html>
<html>

<head>
  <title>Math</title>
  <!-- default css -->
  <link rel="stylesheet" type="text/css" href="css/main.css">

</head>

<body class="math">
  <div class="math__time">0</div>
  <button class="math__start">Start</button>
  
  <div class="math__calc">
    <div class="math__num--wrapper">
      <div class="math__num math__num--one">88</div>
      <span class="math__multiply--symbol">*</span>
      <div class="math__num math__num--two">22</div>
    </div>
    <form class="math__ans">
      <input type="text" name="answer" class="math__ans--user">
    </form>
  </div>

</body>

</html>
1
Sandesh Sapkota 15 mars 2019 à 10:01

2 réponses

Meilleure réponse

Maheer a raison, le seul ajout serait de ne pas polluer votre espace global. Créez une fermeture pour contenir ces variables. J'ai mis à jour la fonction pour retourner une fonction.

Le problème

Votre clearInterval(timeLeft) n'efface en fait rien. Le timeLeft n'est pas défini au moment de la compensation.

La solution

Le déplacement de votre timeleft est dans une portée plus élevée. Tu peux soit: - Mettez-le dans l'espace de noms global (non recommandé) - Créez une portée autour de la fonction timeCalc.

J'ai implémenté la deuxième solution ci-dessous. J'ai d'abord changé le timeCalc(). Maintenant, le timeCalc() produit une fonction. Cette fonction peut être utilisée comme rappel pour le .addEventListener().

Ensuite, l'appel de cette fonction dans le .addEventListener() renverra une fonction de minuterie avec des variables entourées d'une fermeture. J'ai également changé le fulltime dans la fonction en 8 pour afficher 7 secondes après que le compte à rebours a atteint 1.

const timeContainer = document.querySelector('.math__time');
const startBtn = document.querySelector('.math__start');

function timeCalc() {
  let timeLeft = null;
  let fullTime = 7;

  return function() {      
  clearInterval(timeLeft);
  fullTime = 7;
  timeContainer.textContent = fullTime;

  timeLeft = setInterval(function() {
    fullTime--;
    timeContainer.textContent = fullTime;

    if (fullTime === 1) {
      fullTime = 8;
    }
  },1000);
}
}


startBtn.addEventListener('click', timeCalc());
*,
*:before,
*:after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.math {
  background: gray;
  font-family: verdana, sans-serif;
}

.math__calc {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translateY(-50%) translateX(-50%);
}

.math__num {
  margin: 15px;
  color: #fff;
  font-size: 30px;
  padding-left: 100px;
}

.math__num--wrapper {
  position: relative;
}

.math__time {
  padding: 10px;
  background: black;
  color: #fff;
  position: absolute;
  right: 20px;
  top: 20px;
  border: #fff 2px solid;
}
 

.math__start {
  position: absolute;
  left: 20px;
  top: 20px;
  border: 2px solid #fff;
  background: #333;
  color: #fff;
  padding: 10px;
}

.math__multiply--symbol {
  position: absolute;
  bottom: -10px;
  left: 10px;
  font-size: 30px;
}
<!DOCTYPE html>
<html>

<head>
  <title>Math</title>
  <!-- default css -->
  <link rel="stylesheet" type="text/css" href="css/main.css">

</head>

<body class="math">
  <div class="math__time">0</div>
  <button class="math__start">Start</button>
  
  <div class="math__calc">
    <div class="math__num--wrapper">
      <div class="math__num math__num--one">88</div>
      <span class="math__multiply--symbol">*</span>
      <div class="math__num math__num--two">22</div>
    </div>
    <form class="math__ans">
      <input type="text" name="answer" class="math__ans--user">
    </form>
  </div>

</body>

</html>
0
Jordan Maduro 15 mars 2019 à 18:48

Vous devez déclarer timeLeft dans la portée globale et le modifier à l'intérieur de la fonction

const timeContainer = document.querySelector('.math__time');
const startBtn = document.querySelector('.math__start');
let timeLeft;
let fullTime;
function timeCalc() {
  clearInterval(timeLeft);

  fullTime = 7;
  timeContainer.textContent = fullTime;

  timeLeft = setInterval(function() {
    fullTime--;
    timeContainer.textContent = fullTime;

    if (fullTime === 1) {
      fullTime = 8
    }
  },1000);
}


startBtn.addEventListener('click', timeCalc);
*,
*:before,
*:after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.math {
  background: gray;
  font-family: verdana, sans-serif;
}

.math__calc {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translateY(-50%) translateX(-50%);
}

.math__num {
  margin: 15px;
  color: #fff;
  font-size: 30px;
  padding-left: 100px;
}

.math__num--wrapper {
  position: relative;
}

.math__time {
  padding: 10px;
  background: black;
  color: #fff;
  position: absolute;
  right: 20px;
  top: 20px;
  border: #fff 2px solid;
}
 

.math__start {
  position: absolute;
  left: 20px;
  top: 20px;
  border: 2px solid #fff;
  background: #333;
  color: #fff;
  padding: 10px;
}

.math__multiply--symbol {
  position: absolute;
  bottom: -10px;
  left: 10px;
  font-size: 30px;
}
<!DOCTYPE html>
<html>

<head>
  <title>Math</title>
  <!-- default css -->
  <link rel="stylesheet" type="text/css" href="css/main.css">

</head>

<body class="math">
  <div class="math__time">0</div>
  <button class="math__start">Start</button>
  
  <div class="math__calc">
    <div class="math__num--wrapper">
      <div class="math__num math__num--one">88</div>
      <span class="math__multiply--symbol">*</span>
      <div class="math__num math__num--two">22</div>
    </div>
    <form class="math__ans">
      <input type="text" name="answer" class="math__ans--user">
    </form>
  </div>

</body>

</html>
2
Maheer Ali 15 mars 2019 à 07:21