简体   繁体   中英

Why is the my function not being called in my SetInterval?

It's my first time using JS classes. I have a setInterval in a function but the function that is supposed to be repeating but I'm not sure why it's not.

    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();

When you set the onclick property of an element, the function you assign will always be called with the this value set to the element. Thus, the properties of this that you try to access will not be defined.

Instead of:

startButton.onclick = this.startTimer;

Use Function.prototype.bind to set the this value the function will be called with:

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

Also, your code for incrementing the timer is incorrect:

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 is undefined as you used let to declare minutes and seconds. Instead, just reference the variables using their names--ie, minutes and seconds .

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

When you are stopping the timer, you forgot to add this in front of the property you were trying to access.

This:

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

Should be:

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

Demo:

 <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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM