why i should click twice when i want to play againt my stopwatch after reset it?

85 Views Asked by At

i've try to built stopwatch from freecodecamp tutorial, when i add feature to reset it i realize that i should click twice to play after reset it.. any answer or solution for it? btw its my first question and i'm absolute beginner.

i've tried to find solution from other question and chatGPT but does not work.. here's my code :

start.addEventListener('click', function() {
  if (timerStatus === 'stopped') {
    timerInterval = window.setInterval(stopwatch, 1000);
    document.getElementById('start').innerHTML = `<i id="play">Pause</i>`;

    timerStatus = 'started';
  } else if (timerStatus === 'started') {
    window.clearInterval(timerInterval);
    document.getElementById('start').innerHTML = `<i id="play">Play</i>`;

    timerStatus = 'paused';
  } else if (timerStatus === 'paused') {
    timerInterval = window.setInterval(stopwatch, 1000);
    document.getElementById('start').innerHTML = `<i id="play">Pause</i>`;

    timerStatus = 'started';
  }
});


reset.addEventListener('click', function() {

  window.clearInterval(timerInterval);
  seconds = 0;
  minutes = 0;
  hours = 0;
  document.getElementById('start').innerHTML = `<i id="play" >Play</i>`;
  document.getElementById('timer').innerHTML = "00:00:00"
})
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" />

<div class="container">

  <div id="timer">
    00:00:00
  </div>

  <div class="buttons">
    <button id="start">
      <i class="fa-solid fa-play" id="play">Play</i>
    </button>
    <button id="reset">
      <i class="fa-solid fa-arrow-rotate-left" id="reset2">Reset</i>
    </button>
  </div>
</div>

2

There are 2 best solutions below

0
Rory McCrossan On BEST ANSWER

The problem is simply because you're not resetting timerStatus back to stopped when you click the Reset button.

Also note there's a few improvements you can make, such as selecting the elements in the DOM once and storing them in variables you can re-use, setting textContent to just update the node instead of innerHTML to re-write the entire HTML, and placing repeated logic in to reusable functions.

Below is a simplified working example, as the content of the stopWatch method wasn't provided in the question.

let timerInterval;
let timerStatus = 'stopped';
const timer = document.querySelector('#timer');
const start = document.querySelector('#start');
const reset = document.querySelector('#reset');
const play = document.querySelector('#play');

const stopwatch = () => console.log('foo');

const startTimer = () => {
  timerInterval = window.setInterval(stopwatch, 1000);
  play.textContent = 'Pause';
  timerStatus = 'started';
}

const endTimer = () => {
  window.clearInterval(timerInterval);
  play.textContent = 'Play';
  timerStatus = 'paused';
}

start.addEventListener('click', function() {
  if (timerStatus === 'stopped') {
    startTimer();
  } else if (timerStatus === 'started') {
    endTimer();
  } else if (timerStatus === 'paused') {
    startTimer();
  }
});

reset.addEventListener('click', function() {
  endTimer();
  timer.textContent = "00:00:00";
  seconds = minutes = hours = 0;
})
<div class="container">
  <div id="timer">00:00:00</div>
  <div class="buttons">
    <button id="start">
      <i class="fa-solid fa-play" id="play">Play</i>
    </button>
    <button id="reset">
      <i class="fa-solid fa-arrow-rotate-left" id="reset">Reset</i>
    </button>
  </div>
</div>

0
Mister Jojo On

If you want to improve your knowledge...

But it is wrong to expect precise time measurement with a setInterval() method.
You must read setInterval -> delay restrictions

const
  el_Timer = document.querySelector('#timer')
, bt_Start = document.querySelector('#start')
, bt_Reset = document.querySelector('#reset')
  ;
var
  timerInterval = 0
, seconds       = 0
, minutes       = 0
, hours         = 0
  ;
bt_Start.addEventListener('click', () =>
  {
  if ( bt_Start.classList.toggle('Pause') )
    timerInterval = setInterval(stopwatch, 1000);
  else
    clearInterval(timerInterval);
  });
bt_Reset.addEventListener('click', ()=>
  {
  clearInterval(timerInterval);
  el_Timer.textContent      = '00:00:00';
  hours = minutes = seconds = 0;
  bt_Start.classList.remove('Pause');
  })
function stopwatch()
  {
  seconds = ++seconds % 60;
  if (seconds===0)
    {
    minutes = ++minutes % 60;
    if (minutes===0) hours++;
    }
  el_Timer.textContent = hours.toString(10).padStart(2,'0')
                 + ':' + minutes.toString(10).padStart(2,'0')
                 + ':' + seconds.toString(10).padStart(2,'0')
                 ;
   }
.buttons > button {
  width : 8em;
  }
#start.Pause       > i.fa-play  ,
#start:not(.Pause) > i.fa-pause {
  display : none;
  }
#timer {
  font-size : 2em;
  margin    : 1em;
  }
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" />

<div class="container">
  <div id="timer"> 00:00:00 </div>

  <div class="buttons">
    <button id="start">
      <i class="fa-solid fa-play" > Play</i>
      <i class="fa-solid fa-pause"> Pause</i>
    </button>
    <button id="reset">
      <i class="fa-solid fa-arrow-rotate-left" > Reset</i>
    </button>
  </div>
</div>