代码之家  ›  专栏  ›  技术社区  ›  YannB

在类中使用setInterval()和clearInterval()

  •  0
  • YannB  · 技术社区  · 6 年前

    我在理解如何在类中使用setInterval()和clearInterval()时遇到问题。我试图建立一个从0开始直到我决定停止的计时器。

    到目前为止,我设法有一个方法,当你调用它时,计时器会启动,但当我试图暂停它时,它会忽略我的方法并继续。

    HTML

    <!DOCTYPE html>
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
      <body>
        <div class="container">
          <p id="timer">im here</p>
        </div>
        <button>Start/Stop Timer</button>
        <button>Reset Timer</button>
        <script src="script.js"></script>
      </body>
    </html>
    

    JS

    class Timer {
      constructor(){
        this.isRunning = false;
        this.currTimer = 0;
        this.runTimer;
        var timer = document.getElementById('timer');
      }
    
      start(){
        this.isRunning = true;
        if (this.isRunning) {
          var currentTime = this.currTimer;
          this.runTimer = setInterval(function(){
            timer.innerHTML = ++currentTime;
          },1000)
        }
      }
    
      pause(){
        this.isRunning = false;
        if (this.isRunning = false) {
          clearInterval(this.runTimer)
        }
      }
    }
    
    var test = new Timer();
    test.start();
    test.pause();// put this after a few seconds
    

    我也很肯定我用错了“这个”。 我刚学会了这个新东西,并试图建立它。

    2 回复  |  直到 6 年前
        1
  •  3
  •   T.J. Crowder    6 年前

    如果要在构造对象后使用它,则 timer 本地变量需要改为属性,因此在构造函数中,更改

    var timer = document.getElementById('timer');
    

    this.timer = document.getElementById('timer');
    

    然后进入 start ,您需要使用 this.timer 也就是说你想用 箭头函数 ,而不是传统的函数,对于 setInterval 回调以便函数结束 this 。你可能想用 this.currTimer 直接复制而不是复制到变量:

    this.runTimer = setInterval(() => {
        this.timer.innerHTML = ++this.currTimer;
    },1000);
    

    这里的逻辑也需要调整:您刚刚分配了 true this.isRunning ,所以之后不需要检查。但实际上,你需要事先检查一下:

    start(){
      if (!this.isRunning) {
        this.isRunning = true;
        this.runTimer = setInterval(() => {
          this.timer.innerHTML = ++this.currTimer;
        },1000);
      }
    }
    

    你还需要使用 == === 不是 = ,当进行这样的比较时:

    if (this.isRunning = false) { // Needs == or ===
    

    但其中的逻辑 pause 有个问题:你刚刚 这个。正在运行 false ,所以在下一行检查时,它总是错误的。相反,在分配给它之前检查它。另外,使用 if (flag) if (!flag) 而不是使用 == true == false :

    pause(){
      if (this.isRunning) {
        clearInterval(this.runTimer)
        this.isRunning = false;
      }
    }
    

    似乎可以应对这些变化:

    class Timer {
        constructor() {
            this.isRunning = false;
            this.currTimer = 0;
            this.runTimer;
            this.timer = document.getElementById('timer');
        }
    
        start() {
            if (!this.isRunning) {
                this.isRunning = true;
                this.runTimer = setInterval(() => {
                    this.timer.innerHTML = ++this.currTimer;
                }, 1000);
            }
        }
    
        pause() {
            if (this.isRunning) {
                clearInterval(this.runTimer);
                this.isRunning = false;
            }
        }
    }
    
    var test = new Timer();
    test.start();
    setTimeout(function() {
      test.pause(); // put this after a few seconds
    }, 4000);
    <div id="timer"></div>

    我也强烈建议使用 ; 始终如一(例如 设置间隔 )javascript有自动分号插入(asi)功能,因此即使没有,它在某些地方也会像包含分号一样工作,但是除非有 非常 全面了解ASI规则。

        2
  •  0
  •   Robby Cornelissen    6 年前

    在你的情况下,你是分配而不是比较。

    这是:

    pause() {
      this.isRunning = false;
      if (this.isRunning = false) {
        clearInterval(this.runTimer)
      }
    }
    

    应该是:

    pause() {
      this.isRunning = false;
      if (this.isRunning === false) {
        clearInterval(this.runTimer)
      }
    }
    

    或者,因为条件总是求值为真,所以:

    pause() {
      this.isRunning = false;
    
      clearInterval(this.runTimer)
    }