Reputation: 726
I am trying to make an easy countdown but it does not work the way I think it should work. This is the first time I use setInterval
in Javascript and would be very happy if someone could find my mistake.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="text/javascript">
function timer () {
window.clearTimeout(clock)
var seconds = 10;
var clock = setInterval(function() {
if (seconds == 0) {
} else {
seconds = seconds-1;
document.getElementById('seconds').innerHTML = seconds;
};
},1000);
}
</script>
<button onclick="timer();">timer</button>
<p id="seconds">10</p>
</body>
</html>
I hoped the timer would start-over when you clicked the button, but there are 2 timers running at the same time.
Upvotes: 0
Views: 993
Reputation: 3387
There are several problems with your code you need to address:
clock
variable global. In your example, an empty new variable clock
is created each time the timer()
function is called.clearTimeout()
function instead of the clearInterval()
function.setInterval()
function may miss some ticks and your seconds
counter will then be off. If you wish to avoid that, you should check the current time each time the interval function is called.<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">
var clock;
function timer () {
clearInterval(clock);
var start = new Date().getTime();
clock = setInterval(function() {
var seconds = Math.round(10 - (new Date().getTime() - start) / 1000);
if (seconds > 0)
document.getElementById('seconds').innerHTML = seconds;
else
clearInterval(clock);
}, 1000);
}
</script>
<button onclick="timer();">timer</button>
<p id="seconds">10</p>
</body>
</html>
A breakdown of Math.round(10 - (new Date().getTime() - start) / 1000)
:
new Date().getTime()
returns the current time in milliseconds since the epoch.(... - start) / 1000
returns the number of seconds since the start of the timer.10 - ...
returns the number of remaining seconds.Math.round(...)
rounds the result to an integer.Upvotes: 2
Reputation: 122906
Just using setTimeout
simplifies things (you used setInterval
, but clearTimeout
to clear it), declare the necessary variables outside the timer
function and add a reset
argument to be able to reset the timer.
(function () {
var report = document.querySelector('#seconds');
var seconds = 10;
var timed = null;
document.querySelector('button')
.addEventListener('click', function(e) { timer(true) });
timer(true);
function timer (reset) {
seconds -= 1;
if(reset) {
clearTimeout(timed);
seconds = 10;
}
report.textContent = seconds;
if (seconds > 0 ) {
timed = setTimeout(timer, 1000);
}
}
}())
#seconds {
font: 48px/70px bold verdana, arial;
color: white;
width: 70px;
height: 70px;
background: green;
text-align: center;
border-radius: 50%;
}
<button>start/reset timer</button>
<p id="seconds"></p>
Upvotes: 0