javascript 如何控制按钮单击时间隔的执行和取消?

zbdgwd5y  于 2023-02-02  发布在  Java
关注(0)|答案(2)|浏览(114)

我正在尝试更改HTML页面的背景颜色,在单击按钮id = 'button4'时使用setInterval每200毫秒更改一次。我希望在用户再次单击同一按钮时停止更改背景颜色。
setInterval的代码是在赋值给var x时执行的,而我想在'goCrazy'函数被调用时满足条件时执行它,这怎么做呢?
clearInterval工作正常,颜色更改停止。
下面是我的代码。

var x = setInterval(() => {
    const rndInt1 = randomIntFromInterval(0, 255);
    const rndInt2 = randomIntFromInterval(0, 255);
    const rndInt3 = randomIntFromInterval(0, 255);
    document.body.style.backgroundColor = `rgb(${rndInt1}, ${rndInt2}, ${rndInt3})`;
}, 200);

function goCrazy() {

    if (document.getElementById('button4').innerText == 'Go Crazy') {
        document.getElementById('button4').innerText = 'stop';
        x;
    }
    else {
        clearInterval(x);
        document.getElementById('button4').innerText = 'Go Crazy';
    }
}

function randomIntFromInterval(min, max) { // min and max included
    return Math.floor(Math.random() * (max - min + 1) + min)
}
jmp7cifd

jmp7cifd1#

您可以将setInterval中的代码提取到一个命名函数中,并在goCrazy中调用setIntervalclearInterval

var x;

function goCrazy(){
    if (document.getElementById('button4').innerText == 'Go Crazy') {
        document.getElementById('button4').innerText = 'stop';
        x = setInterval(changeBackground, 200);
    }
    else {
        document.getElementById('button4').innerText = 'Go Crazy';
        if (x) clearInterval(x);
    } 
}

function changeBackground() {
    const rndInt1 = randomIntFromInterval(0, 255);
    const rndInt2 = randomIntFromInterval(0, 255);
    const rndInt3 = randomIntFromInterval(0, 255);
    document.body.style.backgroundColor = `rgb(${rndInt1}, ${rndInt2}, ${rndInt3})`;
}

function randomIntFromInterval(min, max) { // min and max included 
    return Math.floor(Math.random() * (max - min + 1) + min)
}
klh5stk1

klh5stk12#

OP首先需要使要在间隔内执行的背景改变功能成为可寻址功能,例如通过将其实现为function statement
第二,OP需要跟踪运行/暂停间隔,可以通过单个事件处理程序来实现这一点,该事件处理程序知道自己的this上下文,在该上下文中,可以向其bind至少timeId,甚至可以向其bind一些附加的与按钮相关的文本数据。
处理函数的实现非常简单,它注册到按钮的'click'event-listener中。
根据绑定timerIdnull值比较,检测'running''halted'间期,这使得易于继续清除运行间期或启动新间期(包括按钮的文本切换)。

function getRandomValue(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min);
}
function setRandomBackgroundColor() {
  document.body.style.backgroundColor =
    `rgb(${getRandomValue(0, 255)},${getRandomValue(0, 255)},${getRandomValue(0, 255)})`;
}

function toggleBackgroundBehaviorFromBoundState({ currentTarget: elmBtn }) {
  let toggleState;

  if ((this.timerId ?? null) !== null) {

    clearInterval(this.timerId);

    // explicitly nullify value due to the above `null` comparison.
    this.timerId = null;

    toggleState = 'halted';
  } else {
    this.timerId = setInterval(setRandomBackgroundColor, 100);

    toggleState = 'running';
  }
  elmBtn.textContent = this?.buttonCopy?.[toggleState];
}

function main() {
  document
    .querySelector('#button4')
    .addEventListener(
      'click',
      toggleBackgroundBehaviorFromBoundState.bind({
        buttonCopy: {
          running: 'Stop',
          halted: 'Go Crazy',
        },
        timerId: null,
      })
    );
}
main();
<button id="button4">Go Crazy</button>

编辑

由于上面的解决方案被称为 "混乱和非惯用的JavaScript",因此我们采用了这个解决方案,并对其进行了调整,以适应似乎受到青睐的this-上下文无关closure-风格。
一个二个一个一个

相关问题