Search code examples
javascriptsetinterval

Why stop button is not working in my javascript code?


// generate a random color - random hex value

const randomColor = function () {
  const hex = '0123456789ABCDEF';
  let color = '#';
  for (let i = 0; i < 6; i++) {
    color += hex[Math.floor(Math.random() * 16)];
  }
  return color;
};

let intervalId;
const startChangingColor = function () {
  intervalId = setInterval(changeBg, 3000);
  function changeBg() {
    document.body.style.backgroundColor = randomColor();
  }
};
const stopChangingColor = function () {
  clearInterval(intervalId);
};

document.querySelector('#start').addEventListener('click', startChangingColor);
document.querySelector('#stop').addEventListener('click', stopChangingColor);

This code has two buttons: one to start and the other to stop. When I click on the start button, the color starts changing. However, when I click on the stop button, it doesn't work; it should stop the color from changing.


Solution

  • Because of how setInterval and clearInterval works, you are better off just calling a stop just before you start to clear out any activate intervals:

    const randomColor = function () {
      const hex = '0123456789ABCDEF';
      let color = '#';
      for (let i = 0; i < 6; i++) {
        color += hex[Math.floor(Math.random() * 16)];
      }
      return color;
    };
    
    let intervalId;
    const startChangingColor = function () {
      stopChangingColor();
      intervalId = setInterval(changeBg, 3000);
      function changeBg() {
        document.body.style.backgroundColor = randomColor();
      }
    };
    const stopChangingColor = function () {
      clearInterval(intervalId);
    };
    
    document.querySelector('#start').addEventListener('click', startChangingColor);
    document.querySelector('#stop').addEventListener('click', stopChangingColor);
    <button id="start">Start</button>
    <button id="stop">Stop</button>

    clearInterval, as you an see in the documentation here, does not care what you pass in:

    If the parameter provided does not identify a previously established action, this method does nothing.

    If it's a valid interval ID it will cancel it, if it's anything else it will be ignored, so there's no need to check if it exists or anything, just clear it with the variable that holds/will hold your ID.