I am trying to build a simple multiplication game using pure Javascript. When I click start button it calls a function timeCalc(). The timeCalc function declares a variable name fullTime with the value of 7 and sets interval and after every second fullTime is decreasing by 1. when it decreases to 1 it sets the fullTime value to 7.
If I click on the start button many times the fullTime decreses so fast and in a disorder way even If I have done clearInterval() at the begining. I want to decrese the fullTime from 7 in a normal way even if I click it many times. what happens behind the scene?
Here is my code snippet. Thank you.
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>
You need to declare timeLeft
in global scope and change it inside function
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>
Maheer is right, only addition would be to not pollute your global space. Create a closure to hold these variables. I updated the function to return a function.
The problem
Your clearInterval(timeLeft)
is actually not clearing anything. The timeLeft
is undefined at the moment of clearing.
The Solution
Moving your timeleft
is in a higher scope. You can either: - Put it in the global namespace (Not recommended) - Create a scope around the timeCalc function.
I implemented the second solution below. I first changed the timeCalc()
. Now the timeCalc()
produces a function. This function can be used as the callback in for the .addEventListener()
.
Then calling that function in the .addEventListener()
will return a timer function with variables enclosed in a closure. I also changed the fulltime
in the function to 8 to show 7 seconds after the countdown reached 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>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.