为什么在我的SetInterval中没有调用我的函数?

时间:2019-04-08 23:32:34

标签: javascript

这是我第一次使用JS类。我在一个函数中有一个setInterval,但是该函数应该重复,但我不确定为什么不重复。

    class Stopwatch 
    {
    constructor(isRunning, timer, timerTime)
    {
        this.isRunning = isRunning;
        this.timer = timer;
        this.timerTime = timerTime; 
    }
    init()
    {
    // Put the element on the page with an id of start in a variable
    // Do the same for the stop button and the reset button
    const startButton = document.getElementById("start");
    const stopButton = document.getElementById("stop");
    const resetButton = document.getElementById("reset");


    // Add an onclick handler to each of the buttons
    // Use the functions startTimer, stopTimer and resetTimer 
    startButton.onclick = this.startTimer;
    stopButton.onclick = this.stopTimer;
    resetButton.onclick = this.resetTimer;
    }
    startTimer() 
    {
        // if the timer is NOT running, start it
        // call the function incrementTimer every second
        // save the timer in a the timer variable

        if(!this.isRunning)
        {
            this.isRunning = true;
            this.timer = setInterval(this.incrementTimer, 1000);

        }
    }

    incrementTimer() 
    {
        // increment the timerTime
        // calculate the number of minutes and seconds
        this.timerTime++;
        let minutes = Math.floor(this.timerTime / 60);
        let seconds = this.timerTime % 60;
        // write the minutes and seconds to the elements on the page
        // use the function pad to make sure there's a leading 0 if necessary
        document.getElementById("minutes").innerHTML = this.pad(this.minutes);
        document.getElementById("seconds").innerHTML = this.pad(this.seconds);

    }

    pad(number) 
    {
        // add a leading 0 if the number is < 10
        if(number < 10)
            number = "0" + number;

        return number;
    }

    stopTimer() 
    {
        // if the timer is running, stop it
        if(this.isRunning)
        {
            isRunning = false;
            timer = clearInterval(timer);
        }

    }

    resetTimer() 
    {
        // stop the timer
        this.stopTimer();

        // set the timerTime back to 0
        this.timerTime = 0;

        // write 00 to the elements on the page for minutes and seconds
        document.getElementById("minutes").innerHTML = "00";
        document.getElementById("seconds").innerHTML = "00";
    }
}



let stopwatch = new Stopwatch(false, null, 0);

// When the page has finished loading, call the function init
window.onload = stopwatch.init();

1 个答案:

答案 0 :(得分:2)

设置元素的onclick属性时,将始终使用元素的this值来调用分配的函数。因此,将不会定义您尝试访问的this的属性。

代替:

startButton.onclick = this.startTimer;

使用Function.prototype.bind设置函数将使用的this值:

startButton.onclick = this.startTimer.bind(this);

此外,您用于递增计时器的代码不正确:

let minutes = Math.floor(this.timerTime / 60);
let seconds = this.timerTime % 60;
document.getElementById("minutes").innerHTML = this.pad(this.minutes);
document.getElementById("seconds").innerHTML = this.pad(this.seconds);
您使用this.minutes来声明分钟和秒,所以未定义

let。相反,仅使用变量名minutesseconds来引用变量。

document.getElementById("minutes").innerHTML = this.pad(minutes);
document.getElementById("seconds").innerHTML = this.pad(seconds);

停止计时器时,您忘记在要访问的属性前面添加this

此:

if(this.isRunning){
    isRunning = false;//isRunning is not defined as a local or global variables
    timer = clearInterval(timer);//timer is not defined
}

应该是:

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

演示:

<button id="start">
Start
</button>
<button id="stop">
Stop
</button>
<button id="reset">
Reset
</button>
<span id="minutes"></span>:<span id="seconds"></span>
<script>
    class Stopwatch 
    {
    constructor(isRunning, timer, timerTime)
    {
        this.isRunning = isRunning;
        this.timer = timer;
        this.timerTime = timerTime; 
    }
    init()
    {
    // Put the element on the page with an id of start in a variable
    // Do the same for the stop button and the reset button
    const startButton = document.getElementById("start");
    const stopButton = document.getElementById("stop");
    const resetButton = document.getElementById("reset");


    // Add an onclick handler to each of the buttons
    // Use the functions startTimer, stopTimer and resetTimer 
    startButton.onclick = this.startTimer.bind(this);
    stopButton.onclick = this.stopTimer.bind(this);
    resetButton.onclick = this.resetTimer.bind(this);
    }
    startTimer() 
    {
        // if the timer is NOT running, start it
        // call the function incrementTimer every second
        // save the timer in a the timer variable
        if(!this.isRunning)
        {
            this.isRunning = true;
            this.timer = setInterval(this.incrementTimer.bind(this), 1000);
        }
    }

    incrementTimer() 
    {
        // increment the timerTime
        // calculate the number of minutes and seconds
        this.timerTime++;
        let minutes = Math.floor(this.timerTime / 60);
        let seconds = this.timerTime % 60;
        // write the minutes and seconds to the elements on the page
        // use the function pad to make sure there's a leading 0 if necessary
        document.getElementById("minutes").innerHTML = this.pad(minutes);
        document.getElementById("seconds").innerHTML = this.pad(seconds);

    }

    pad(number) 
    {
        // add a leading 0 if the number is < 10
        if(number < 10)
            number = "0" + number;

        return number;
    }

    stopTimer() 
    {
        // if the timer is running, stop it
        if(this.isRunning)
        {
            this.isRunning = false;
            this.timer = clearInterval(this.timer);
        }

    }

    resetTimer() 
    {
        // stop the timer
        this.stopTimer();

        // set the timerTime back to 0
        this.timerTime = 0;

        // write 00 to the elements on the page for minutes and seconds
        document.getElementById("minutes").innerHTML = "00";
        document.getElementById("seconds").innerHTML = "00";
    }
}



let stopwatch = new Stopwatch(false, null, 0);

// When the page has finished loading, call the function init
window.onload = stopwatch.init();
</script>