Im working on code for a simple stopwatch. Last obstacle for me is reset the time to zero. The function resetTimer is where i am trying to implement the code. So the webpage will display a page with a timer and three buttons; stop, start and reset. When a user clicks the reset button, the timer is supposed to reset back to zero. I have been having trouble trying to make it work. Any help/ideas would be clutch. I hope i made myself clear. Again i am trying to make the timer reset to 00:00:00
window.onload = function () { //grab possible elements needed const timerEl = document.getElementById("timer-text") const startBtn = document.getElementById("start") const restartBtn = document.getElementById("restart"); const stopBtn = document.getElementById('stop'); //hold variables of time and set to 0 let hours = parseInt('0'); let minutes = parseInt('0'); let seconds = parseInt('0'); let time; function makeTwoNumbers(num) { if (num < 10) { return "0" + num } return num } //timer let timer = () => { seconds++ //console.log(seconds) if (seconds == 60) { minutes++ seconds = 0; hours = 0 } if (minutes == 60) { hours++ minutes = 0; hours = 0; } timerEl.textContent = makeTwoNumbers(hours)+ ": " + makeTwoNumbers(minutes) + ": " + makeTwoNumbers(seconds); } let runTheClock; //timer is running function runTimer() { runTheClock = setInterval(timer, 20);; } function stopTimer() { clearInterval(runTheClock) } //function will reset timer function resetTimer() { time--; timerEl.textContent; if (time === 0) { stopTimer(); time = 0 } } restartBtn.addEventListener("click", function () { resetTimer(); }) //button will pause the timer stopBtn.addEventListener("click", function () { stopTimer(); }) //button will start the timer startBtn.addEventListener("click", function () { runTimer(); }) }
Advertisement
Answer
Here’s a fixed and slightly refactored version.
<html> <body> <div id="timer-text"></div> <button id="start">start</button> <button id="restart">restart</button> <button id="stop">stop</button> </body> <script> const timerEl = document.getElementById("timer-text") const startBtn = document.getElementById("start") const restartBtn = document.getElementById("restart"); const stopBtn = document.getElementById('stop'); let runTheClock; let seconds = 0; render(seconds); function makeTwoNumbers(num) { return ((num < 10) ? "0" : "") + num; } function tick() { seconds++; render(seconds); } function render(secs) { const hours = Math.floor(secs / 3600); const minutes = Math.floor(secs / 60) - (hours * 60); const seconds = secs % 60; const val = [hours, minutes, seconds].map(makeTwoNumbers).join(":"); console.log(val); timerEl.textContent = val; } function runTimer() { runTheClock = setInterval(tick, 1000); } function stopTimer() { clearInterval(runTheClock) } function resetTimer() { seconds = 0; render(seconds); } restartBtn.addEventListener("click", resetTimer); stopBtn.addEventListener("click", stopTimer); startBtn.addEventListener("click", runTimer); </script> </html>
In the reset function it just sets seconds back to 0 and sets the textContent
value so it appears on the page. I separated out the calculating and drawing of the time into a render
fucntion, so it can be reused whenever it needs to be re-rendered.
To explain the render function.
We only need to store the number of seconds as a persistent variable between the periodic function calls. We can derive hours and minutes from it. This makes it much less error prone than trying to increment hours and minutes as well.
To calculate hours we just divide seconds by 3600 (or 60 x 60 the number of seconds in an hour) and round down.
To calculate minutes we can calculate the number of total minutes (seconds / 60 and round down) then subtract the number of minutes in the hours value we calculated (hours * 60).
For seconds we use modulus or %
which is just a fancy word for remainder. So seconds % 60
gives us the remainder value of seconds / 60
. For example 61 % 60 = 1. This isn’t the only way these values could be calculated.
To build the display string. I just put all of the hours, minutes and seconds in an array. Then used the map
method, which applies the function makeTwoNumbers
to all of the values. I then used the join
method to join all the strings using the delimiter :
. It just saves some typing and means you only reference makeTwoNumbers
once, making it less work to use a different function later if you want to.
Hope that helps.