Home > front end >  do something when timer ends [JS]
do something when timer ends [JS]

Time:10-31

I have a timer, I want to do something when textContent of div element === 0;

JS:

function createTimer() {
        const display = document.createElement('div');
        display.classList.add('display');
        display.id = 'display';
        display.textContent = '5';

        return display;
    };

let intervalID;

function startTimer() {
        resetTimer();
        intervalID = setInterval(() => {
            let displayTimer = document.getElementById('display');
            let displayNumber = parseInt(displayTimer.textContent);
            if (displayTimer.textContent !== '0') displayTimer.textContent = displayNumber - 1;
        }, 1000);
    };

function resetTimer() {
        clearInterval(intervalID);
    };


function someFunc() {
    // here is a lot of code stuff and timer is working correctly
    const timer = createTimer();
};

This is what i tried:

function someFunc() {
    const timer = createTimer();


    timer.addEventListener('input', () => {
            if (timer.textContent === '0') {
                console.log(true);
            };
        });
};

As far as I understood correctly, by creating input event on timer, I always get timer.textContent when it changes, right? I keep track of all the changes thats happening in this div element.

nothing happens.. am i dumb?

CodePudding user response:

Keep track of your count as a number in JavaScript. This creates clarity in what the count is and how it can be manipulated.

Inside the setInterval callback, check if the count is 0. The interval is already there and will run every second, so it makes sense to check it in that place.

The example below is a modified version of your script with the suggested implementation. Since you're returning the display element from the createTimer function I've decided to reuse it in the startTimer function. That way you don't have to select the element from the DOM, as you already have a reference to the element.

As a bonus an extra argument which can be callback function to do something whenever the timer ends.

let count = 5;
let intervalID;

function createTimer() {
  const display = document.createElement('div');
  display.classList.add('display');
  display.id = 'display';
  display.textContent = '5';
  return display;
};

function resetTimer() {
  clearInterval(intervalID);
};

function startTimer(timer, onFinish) {
  resetTimer();

  intervalID = setInterval(() => {
    if (count !== 0) {
      count--;
    }
    
    if (count === 0) {
      resetTimer();
      
      if (typeof onFinish === 'function') {
        onFinish();
      }
    }
    
    timer.textContent = count;
  }, 1000);
};


function someFunc() {
  const timer = createTimer();
  document.body.append(timer);

  startTimer(timer, () => {
    console.log('Done');
  });
};

someFunc();

CodePudding user response:

The input event fires when the value of an <input>, <select>, or <textarea> element has been changed by user. It does not fire when setting the textContent programmatically.

You can use the MutationObserver API to observe the node change.

const timer = createTimer();
new MutationObserver(() => {
    let timer = document.getElementById('display');
    if (timer.textContent === '0') {
        console.log(true);
    };
}).observe(timer, { childList: true });

CodePudding user response:

You could implement the timer with the help of async/await code. It makes the code a lot more cleaner, by having your start and end code in the same function.

const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

function createTimer(name) {
  const element = document.createElement("div");
  element.classList.add("timer");
  document.body.appendChild(element);
  element.textContent = name ": -";
  return async function(seconds) {
    for (let second = seconds; second >= 0; second--) {
      element.textContent = name ": " second;
      if (second > 0) {
        await wait(1000);
      }
    }
  };
}

async function someFunc() {
  const timer = createTimer("First timer");
  console.log("first timer started", new Date());
  await timer(10);
  console.log("timer ended", new Date());
  await wait(2500);
  console.log("first timer started again", new Date());
  await timer(5);
  console.log("first timer ended again", new Date());
}
async function someOtherFunc() {
  const timer = createTimer("Second timer");
  console.log("second timer started", new Date());
  await timer(20);
  console.log("second timer ended", new Date());
}
someFunc();
someOtherFunc();
.timer {
  text-align: center;
  font-size: 2em;
  font-family: sans-serif;
}

  • Related