skip to Main Content

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

Answers


  1. 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>
    Login or Signup to reply.
  2. 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);
      seconds =  minutes = hours = 0;
      bt_Start.classList.remove('Pause');
      el_Timer.textContent = '00:00:00';
      })
    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 > i.fa-solid:after {
      content : ' Play';
      }
    #start.Pause > i.fa-solid:after {
      content : ' Pause';
      }
    #reset > i.fa-solid:after {
      content : ' Reset';
      }
     <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"></i>
        </button>
        <button id="reset">
          <i class="fa-solid fa-arrow-rotate-left" id="reset2"></i>
        </button>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search