-1

I made a timer that will reach zero. and when it reaches zero make the timer run again. the timer goes back to the starting number but doesnt run again. also when i call it again the numbers just start to jump. the code:

var timerPlace = document.getElementById('timer');
var timerP = document.getElementById('timerHard');
var stopTimer;
var toStop;

function timeMed() {
    console.log('im in!')

    var counter = 0;
    var timeLeft = 5;

    timerPlace.innerHTML = '00:45';

    function timeIt() {
        console.log('here')
        counter++
        timerPlace.innerHTML = convertSeconds(timeLeft - counter); 

        if (timerPlace.innerHTML == '00:00') {
            clearInterval(stopTimer);
            resetExercise();
            timeMed();
        }

    }
    function convertSeconds(s) {
        var sec = s % 60;
        var min = Math.floor((s % 3600) / 60);

        return ('0' + min).slice(-2) + ':' + ('0' + sec).slice(-2);
    }

    if (!stopTimer) {
        stopTimer = setInterval(timeIt, 1000);
    }
}
Sufferring
  • 49
  • 5

2 Answers2

0

You only call setInterval() when stopTimer is not set. But after the countdown completes, stopTimer is still set to the ID of the old interval timer, so you don't restart it. You should clear the variable when you call clearInterval().

    if (timerPlace.innerHTML == '00:00') {
        clearInterval(stopTimer);
        stopTimer = null;
        resetExercise();
        timeMed();
    }
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

Modern ES6 Approach and best practices.

I've decided to take the chance and refactor your code a little with Javascripts best practices in mind.

I've added comments which explain the code, and the engineering considerations.

The baseline for the timer is taken from the excellent answer here: https://stackoverflow.com/a/20618517/1194694

// Using destructuring on the paramters, so that the keys of our configuration object, 
// will be available as separate parameters (avoiding something like options.duraitons and so on.
function startTimer({duration, onUpdate , infinite}) {
    let timer = duration, minutes, seconds;
    let interval = setInterval(function () {
        minutes = parseInt(timer / 60);
        seconds = parseInt(timer % 60);
        
        // you can also add hours, days, weeks ewtc with similar logic
        seconds = seconds < 10 ? `0${seconds}` : seconds;
        minutes = minutes < 10 ? `0${minutes}` : minutes;

        
        // calling your onUpdate function, passed from configuraiton with out data
        onUpdate({minutes, seconds});

        if (--timer < 0) {
         // if infinite is true - reset the timer
          if(infinite) {
            timer = duration;
          } else {
            // Clearing the interval + additonal logic if you want
            // I would also advocate implementing an onEnd function,  
            // So that you'll be able to decide what to do from configuraiton.
            clearInterval(interval);
          }
        }
        
    }, 1000);
}

const duration = 5;
const displayElement = document.querySelector("#timer");
startTimer({
  duration,
  onUpdate: ({minutes, seconds}) => {
    // now you're not constraint to rendering it in an element,
    // but can also Pass on the data, to let's say your analytics platform, or whatnot
    displayElement.textContent = `${minutes}:${seconds}`;
  },
  infinite: true
});
<div id="timer">
</div>
silicakes
  • 6,364
  • 3
  • 28
  • 39