I have a keyup event to start a timer but I do not understand why it stops on keydown. It is working as intended but I am having trouble understanding why its working. Why does the timer stop on keydown? I am not calling the stopWatch function anywhere in the keydown event listener. I have gone through every possible scenario I can think of but it is still not making sense to me.

let cubeTimer = document.getElementById("cubeTimer");
let appendMinutes = document.getElementById("minutes");
let appendSeconds = document.getElementById("seconds");
let appendMilliseconds = document.getElementById("milliseconds");
let scramble = document.getElementById("scramble");

let minutes = 0;
let seconds = 0;
let milliseconds = 0.00;
let start = true;
let stop = false;
let arr = [];
let interval;
let scrambleArray = ["R", "L", "R'", "L'", "U", "D", "U'", "D'", "F", "B", "F'", "B'", "R2", "L2", "U2", "B2", "D2", "F2"];

function scrambleCube () {
    let newArr = []
    for (let i = 0; i < 21; i++) {
        if (newArr.length >= 1) {
            newArr.push(scrambleArray[Math.floor(Math.random() * 18)]);
            do {
                newArr[i] = scrambleArray[Math.floor(Math.random() * 18)]
            } while (newArr[i][0] === newArr[i - 1][0]);
        }; 
        if (newArr.length < 1) {
            newArr.push(scrambleArray[Math.floor(Math.random() * 18)]);
        };
        
    };

    for (let i = 0; i < newArr.length; i++) {
        newArr[i] = " " + newArr[i]
    };

    scramble.innerHTML = newArr;
    
    //console.log(newArr)
    
}
scrambleCube()

document.addEventListener("keydown", () => {
    
    arr.push("a");
    if (arr.length > 10) {
        cubeTimer.style.color = "green";
        cubeTimer.style.fontSize = "40px";
        start = true;
        stop = false;
        minutes = 0;
        seconds = 0;
        milliseconds = 0.00;
        appendMinutes.innerHTML = "00";
        appendSeconds.innerHTML = "00";
        appendMilliseconds.innerHTML = "00";
    } else if (arr.length < 10) {
        cubeTimer.style.color = "red";
    }

    if (start === false) { stop = true };
    
    
});

document.addEventListener("keyup", () => {
    start = false;
    cubeTimer.style.color = "green";
    if (arr.length > 10) {
        interval = setInterval(stopWatch, 10);    
    }
    arr = [];
});



function stopWatch () {
    if (stop === true) {  
        clearInterval(interval);
        scrambleCube()
    };

    milliseconds++;

    if (milliseconds == 100) {
        seconds++;
        milliseconds = 0;
    };
    
    if  (seconds == 60) {
        minutes++;
        seconds = 0;
    };

    let milliString = milliseconds;
    let secondString = seconds;
    let minuteString  = minutes;
    
    if (minutes < 10) {
        minuteString = "0" + minuteString;
    };

    if (seconds < 10) {
        secondString = "0" + secondString;
    };

    if (milliseconds < 10) {
        milliString = "0" + milliString;
    };

    appendMinutes.innerHTML = minuteString;
    appendSeconds.innerHTML = secondString;
    appendMilliseconds.innerHTML = milliString;
    
};
1

There are 1 best solutions below

1
Minh Ho On

Even though you are not calling the function stopWatch() anywhere in the keydown event listener. The keyup event listener runs your stopWatch function() in the intervals of 10 milliseconds.

if (arr.length > 10) {
        interval = setInterval(stopWatch, 10);    
    }

So it will keep calling stopWatch() every 10 milliseconds until the interval is cleared. And when you keydown then it would set stop to true which satisfies this condition of yours in the next stopWatch() call:

if (stop === true) {  
    clearInterval(interval);
    scrambleCube()
};

So it would clearInterval, the stopWatch function would stop calling and that is why your code is working.