Home > Software design >  Start and stop interval on button click
Start and stop interval on button click

Time:11-07

I have this code here and i want the background to stop changing when i click the same button (the interval to stop). But i cannot work my way around it.(The else part works because in the console isCicked changes it's value).

let btn = document.querySelector('#btn');
let body = document.querySelector('body');
let isClicked = false;

btn.addEventListener('click', function(){
    let x;
    let y;
    if(isClicked == false){
        isClicked = true;
         x= setInterval(function(){
            let r,g,b;
            r = Math.round(Math.random() * 255);
            g = Math.round(Math.random() * 255);
            b = Math.round(Math.random() * 255);
            body.style.backgroundColor = `rgb(${r},${g},${b})`;
            btn.classList.toggle('button-style')
        },1000)
    }else{
        isClicked = false;
        clearInterval(x);
    }
    console.log(isClicked);

})
<button type="button" id="btn">Click</button>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

To fix your current code you need to declare x outside the event listener since as it stands you redeclare it on each click and overwrite your stored interval id.

let isClicked = false;
let x;

btn.addEventListener('click', function(){
    if(isClicked == false){
        isClicked = true;
        x = setInterval(function(){
    
    ...
}

But you can actually simplify a little by combining isClicked and x and just checking if an interval is stored.

let btn = document.getElementById('btn');
let body = document.querySelector('body');

let interval = null;

btn.addEventListener('click', function () {
  if (interval === null) {
    interval = setInterval(function () {
      let r, g, b;
      r = Math.round(Math.random() * 255);
      g = Math.round(Math.random() * 255);
      b = Math.round(Math.random() * 255);
      body.style.backgroundColor = `rgb(${r},${g},${b})`;
      btn.classList.toggle('button-style');
    }, 1000);
  } else {
    clearInterval(interval);
    interval = null;
  }
  console.log(interval);
});
<button type="button" id="btn">Click</button>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Rather then trying to manage the state of setInterval, you could use setTimeout and recursion (a function calling itself) to create an interval. Likewise, rather than using variable mutation, since you're toggling a class on the button, you can just use the button itself as the exit condition for the recursion.

let btn = document.querySelector('#btn'),
    body = document.querySelector('body');

function ChangeBackground() {
  if (btn.classList.contains('button-style')) { //check exit condition
    body.style.backgroundColor = '#'   Math.random().toString(16).slice(-6);        
    setTimeout(ChangeBackground, 1000); //recursion
  }
}

btn.addEventListener('click', function(){
  this.classList.toggle('button-style'); //toggle exit condition
  ChangeBackground(); //start recursion
});
<button type="button" id="btn">Click</button>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related