简体   繁体   中英

Cannot use 'keydown' and keyup' event listeners on the same div

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>

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

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>

you need to put timerStarted = true inside the keyUp event and the if function. That way it will work correctly.

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