【问题标题】:Start and stop interval on button click单击按钮时的开始和停止间隔
【发布时间】:2021-11-07 21:34:41
【问题描述】:

我在这里有这段代码,我希望当我单击同一个按钮时背景停止变化(停止的间隔)。但我无法解决它。(else 部分有效,因为在控制台中 isCicked 改变了它的值)。

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>

【问题讨论】:

  • 你需要在监听器之外声明x。您在每次单击时重新声明它并覆盖间隔 id,因此无需清除任何内容。

标签: javascript jquery intervals


【解决方案1】:

要修复您当前的代码,您需要在事件侦听器之外声明 x,因为您在每次点击时重新声明它并覆盖您存储的间隔 id。

let isClicked = false;
let x;

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

但是您实际上可以通过结合isClickedx 并检查是否存储了一个区间来简化一点。

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>

【讨论】:

    【解决方案2】:

    然后尝试管理setInterval 的状态,您可以使用setTimeout 和递归(一个调用自身的函数)来创建一个间隔。同样,由于您在按钮上切换一个类,而不是使用变量突变,您可以只使用按钮本身作为递归的退出条件。

    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>

    【讨论】:

    • 递归似乎是一个很好的解决方案,更多关于权衡的讨论在这里:recursive function vs setInterval vs setTimeout javascript,但您的颜色计算有时会返回无效字符串。
    • 从这篇文章的评论中复制了颜色生成器:stackoverflow.com/questions/1484506/random-color-generator。选择它是因为它是一个简短的单行并且投票很高。不过不能说我曾经真正使用过它。
    • 谁会想到有人会发布无效代码,而人们会在没有测试的情况下对其进行投票?!?我在之前的评论中从帖子中选择了另一个衬垫,它在 100 万次迭代中测试了 100%,所以我将其称为有效。供将来参考(Math.random()*0xFFFFFF<<0).toString(16) 无效。感谢您指出这一点。
    猜你喜欢
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    相关资源
    最近更新 更多