Taking a stab at a Javascript Timer and failing

Tags:



let hours =0;
let minutes = 0;
let seconds = 0;
let displayHrs = document.getElementById("hours");
let displayMins = document.getElementById("minutes");
let displaySecs = document.getElementById("seconds");



var interval;
const startBtn =  document.getElementById("start");
const stopBtn =  document.getElementById("stop");
const resetBtn =  document.getElementById("reset");


const  startTimer  = () => {

    seconds++;
    if(seconds < 9){
        displaySecs.innerHTML = "0" + seconds;
    }
    if(seconds > 9){
        displaySecs.innerHTML = seconds;
    }
   if(seconds > 60){
        minutes++;
        seconds = seconds -(minutes *60);
    }
    if (minutes < 9){
        displayMins.innerHTML = "0" + minutes;
    }
     if (minutes > 9){
        displayMins.innerHTML = minutes;
    }
     if (minutes> 60){
        hours++;
        minutes = minutes -(minutes *60);
    }
};
startBtn.onclick = () => {
   interval = setInterval( startTimer);
}

The simple application crashes when I click the startBtn by indicating that displaySecs is null. I watched several tutorial and tried to create my own custom timer. Are there too many if statements? Is there a simpler cleaner way to do this?

Answer

this way:

let hours   = 0
  , minutes = 0
  , seconds = 0
  , interval
  ;
const startBtn  = document.getElementById('start')
  ,   stopBtn   = document.getElementById('stop')
  ,   resetBtn  = document.getElementById('reset')
  , displayHrs  = document.getElementById('hours')
  , displayMins = document.getElementById('minutes')
  , displaySecs = document.getElementById('seconds')
  ;
const  startTimer = () =>
  {
  seconds++
  if (seconds > 60)
    {
    minutes++;
    seconds = 0
    }   
  if (minutes > 60)
    {
    hours++;
    minutes = 0
    }
  displaySecs.textContent = ((seconds < 10)?'0':'') + seconds 
  displayMins.textContent = ((minutes < 10)?'0':'') + minutes 
  displayHrs.textContent  = ((hours < 10)?'0':'') + hours 
  }
startBtn.onclick = () =>
  {
  startBtn.disabled = true
  stopBtn.disabled  = false
  interval = setInterval( startTimer, 1000)
  }
stopBtn.onclick = () =>
  {
  startBtn.disabled = false
  stopBtn.disabled  = true
  clearInterval(interval)
  }
resetBtn.onclick = () =>
  {
  startBtn.disabled = false
  stopBtn.disabled  = true
  clearInterval(interval)
  hours = minutes = seconds = 0
  displaySecs.textContent = displayMins.textContent = displayHrs.textContent = '00'
  }
<p>
  <span id="hours">00</span>h
  <span id="minutes">00</span>m
  <span id="seconds">00</span>s
</p>

<button id="start">start</button>
<button id="stop" disabled>stop</button>
<button id="reset">reset</button>

following the PO’s comments for a request for additional explanation on:

displaySecs.textContent = ((seconds < 10)?'0':'') + seconds 

this is like

displaySecs.textContent = (seconds < 10)?'0':''; // set value to character zero if the value
                                                // of second is less than 10
                                               
                                              // otherwise set an empty string

displaySecs.textContent += seconds;  // add the value of seconds             

(seconds < 10)?'0':'' is Conditional (ternary) operator
it is like this function :

function F(second) {
  if (seconds < 10) return '0'  // return string with a character of zéro
  else              return ''   // return an empty string 
}

Nb: your code use an oposite test if(seconds > 9) == if the value is greather than 9. I believe I read somewhere that testing if an integer is less than 10 requires less cycle for the processor than testing if it is supper to 9 – this needs to be verified (but it’s not very important, it’s just a matter of habit).
.

if my code was without parentheses before the + seconds as:

displaySecs.textContent =  (seconds < 10)?'0':''  + seconds 

it would be interpreted as follows:

displaySecs.textContent =  (seconds < 10) ? '0' : (''+ seconds) 

and would just output the character zero for all values less than 10 (zero through nine) – which would be an error

so I have to precise the order of imperetation with correct parentheses:

displaySecs.textContent = ( (seconds < 10) ? '0' : '' ) + seconds 

hope this explanation will help you?



Source: stackoverflow