Reputation: 17
I want to be able to start a timer when the space bar is released and to stop it when the space bar is pressed. The code I am using right now initially achieves this. However it does not work on subsequent attempts. I am using a boolean to store whether the key has been pressed in the last .5 seconds (in order to not trigger the event again when the user releases the space bar). This code only works on the first attempt
const timer = document.querySelector('#timer')
const playArea = document.querySelector('#play-area')
let timerStarted = false
// starts timer when spacebar is released
playArea.addEventListener('keyup', (e) => {
if (e.keyCode === 32 && !timerStarted) startTimer()
})
// start timer function
function startTimer() {
// assigning time values to zero
let [milliseconds, seconds, minutes] = [0, 0, 0]
let Interval
// actual timer code
Interval = setInterval(() => {
milliseconds++
if (milliseconds % 100 === 0) {
milliseconds = 0
seconds++
}
if (seconds % 60 === 0 && seconds !== 0) {
seconds = 0
minutes++
}
timer.innerText = `${minutes}:${seconds}.${milliseconds}`
}, 10)
playArea.addEventListener('keydown', (e) => {
if (e.keyCode === 32) stopTimer(Interval)
})
}
function stopTimer(interval) {
clearInterval(interval)
timerStarted = true
setTimeout(function () {
timerStarted = false
console.log(timerStarted)
}, 500)
console.log(timerStarted)
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/public/css/style.css">
<script src="/public/js/timer.js" defer></script>
</head>
<body>
<section id="play-area" tabindex="-1">
<h1 id="timer">00:00</h1>
</section>
</body>
</html>
Upvotes: 0
Views: 76
Reputation: 30
you need to put timerStarted = true
inside the keyUp event and the if function. That way it will work correctly.
Upvotes: 0
Reputation: 1895
I have just changed a little bit of your code.
const timer = document.querySelector("#timer");
const playArea = document.querySelector("#play-area");
let timerStarted = false;
let Interval;
playArea.addEventListener("keypress", (e) => {
if (e.keyCode == 32) {
if (!timerStarted) {
timerStarted = true;
startTimer();
} else {
timerStarted = false;
stopTimer(Interval);
}
}
});
// start timer function
function startTimer() {
timerStarted = true;
let [milliseconds, seconds, minutes] = [0, 0, 0];
Interval = setInterval(() => {
milliseconds++;
if (milliseconds % 100 === 0) {
milliseconds = 0;
seconds++;
}
if (seconds % 60 === 0 && seconds !== 0) {
seconds = 0;
minutes++;
}
timer.innerText = `${minutes}:${seconds}.${milliseconds}`;
}, 10);
}
function stopTimer(interval) {
clearInterval(interval);
}
see the below code
playArea.addEventListener("keyup", (e) => {
if (e.keyCode == 32 && !timerStarted) {
console.log("pressed again");
timerStarted = true;
startTimer();
}
});
playArea.addEventListener("keydown", (e) => {
console.log("click");
if (e.keyCode == 32) {
timerStarted = false;
stopTimer(Interval);
}
});
Now the timer will stop on key down (hold the spacebar), but simultaneously timer will start again because of you have released key again.
Solution using two keys
spacebar
to start and s
key to stop.
playArea.addEventListener("keyup", (e) => {
if (e.keyCode == 32 && !timerStarted) {
console.log("pressed again");
timerStarted = true;
startTimer();
}
});
playArea.addEventListener("keydown", (e) => {
if (e.keyCode == 83) {
timerStarted = false;
stopTimer(Interval);
}
});
Upvotes: 1
Reputation: 207537
Your code will add a bunch of event listeners to your element every time you create a new timer instance. Also intervals are not accurate so your time will drift the longer it runs. It is better to use timestamps to determine how long it has been running.
Basic idea
class Timer {
interval = null
startTime = null
constructor(outputElem) {
this.outputElem = outputElem;
}
displayOutput () {
this.outputElem.textContent = this.formatMS(Date.now() - this.startTime);
}
formatMS (ms) {
return new Date(ms).toISOString().substring(11, 23);
}
start () {
if (this.interval) return;
this.startTime = Date.now();
this.displayOutput();
this.interval = window.setInterval(() => this.displayOutput(), 10);
}
stop () {
if (!this.interval) return;
window.clearInterval(this.interval);
this.interval = null;
this.displayOutput();
}
}
const timerElem = document.querySelector('#timer')
const playArea = document.querySelector('#play-area')
const myTimer = new Timer(timerElem);
playArea.addEventListener('keyup', (e) => {
if (e.code === "Space") myTimer.start()
});
playArea.addEventListener('keydown', (e) => {
if (e.code === "Space") myTimer.stop();
});
<section id="play-area" tabindex="-1">
<h1 id="timer">00:00</h1>
</section>
Upvotes: 1