0

To start, I am brand new to Javascript so please excuse my naivete.

I am working on a countdown timer to start on a button click. The timer does start on the click, however, the seconds timer immediately changes (minus 1) and then after that proceeds to countdown every second (as desired).

for example: timer is at 25:00. button is clicked, timer immediately drops to 24:59 (without a second passing) then proceeds to countdown as normal.

Thank you in advance.

let min = 25;
let sec = 60;
let remainSec = sec % 1;

let minText = document.getElementById('minutes');
minText.innerText = min;      //declared outside of sample

let secondsText = document.getElementById('seconds'); 
secondsText.innerText = remainSec + '0'  ;     //declared outside of sample

startTime.addEventListener('click', decrement); //declared outside of sample

function decrement() {
  sec--;
  secondsText.innerText = sec;
  if (sec < 10){
    secondsText.innerText = '0' + sec;
  }
  setInterval(decrement, 1000);
}
mokate
  • 43
  • 1
  • 7

2 Answers2

0

You can use a timeout:

startTime.addEventListener('click', function() { setTimeout(decrement,1000) });
connexo
  • 53,704
  • 14
  • 91
  • 128
0

You don't need the setInterval inside the decrement function, this way it will be called multiple times, and the decrement will occur more then once per second.

Do something like this:

startTime.addEventListener('click', decrement); //declared outside of sample

let interval;

function startDecrement() {
    if (!interval) { // avoid duplicate interval
        interval = setInterval(decrement, 1000);
    }
}

function decrement() {
  sec--;
  secondsText.innerText = sec;
  if (sec < 10){
    secondsText.innerText = '0' + sec;
  }
}

Another cool stuff is that storing the interval allows you cancelling it using the [clearInterval()]( https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearInterval) function.

function stopDecrement() {
    clearInterval(interval);
    interval = null;
}

Additional information

The if statement that checks if a interval was already declared works because javascript any value in a Truthy or Falsy value when using with ! (NOT operator). See Understanding JavaScript Truthy and Falsy

So, when you call setInterval() it returns an unique non-zero integer that identifies the interval, allowing you to cancel it in the future.

On the first run, the interval variable is empty because we just declared it without a value.

let interval;
console.log(interval); // undefined
console.log(!interval); // true 

interval = setInterval(decrement, 1000);

console.log(interval); // 1
console.log(!interval); // false
Elias Soares
  • 9,884
  • 4
  • 29
  • 59
  • thanks for the alternate approach. i'm a little confused though. how would interval become !interval? – mokate Oct 30 '19 at 01:59
  • The `!` is a NOT operator. In JavaScript doing an if like this will check if the variable is empty or falsy (`undefined, null, '', 0, false`) – Elias Soares Oct 30 '19 at 07:14
  • yes, but how does it become false? does declaring it in the if() as !interval make it false? I guess I just am having trouble understanding how the language recognizes whether interval is true or false at any given time without a trigger. – mokate Oct 30 '19 at 14:10
  • 1st. When you call `setInterval` it returns a integer that identifies it. 2nd. When you use the NOT operator on any type on javascript, it's converted to a boolean. For this, javascript have some conventions on what is considered true and false. Any number != 0 is considered true. Any empty variable (undefined or null) is considered false. – Elias Soares Oct 30 '19 at 15:10
  • I've edited the post to add more detailed explanation. – Elias Soares Oct 30 '19 at 15:19