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>