skip to Main Content

I need to execute a setInterval function only when a specific key (F in this case) is being pressed, and then clear it when the key is not pressed.

So far, I have tried this:

var process;

function func(){
    console.log('just for example');
}

window.addEventListener("keydown", (e)=>{
    if(e.key === "f") process = setInterval(func, 100);
});

window.addEventListener("keyup", (e)=>{
    if(e.key === "f") clearInterval(process), process = null;
});

But when I release the F key, the function keeps on executing.
Any help is very much appreciated!

3

Answers


  1. Use ??= to set the interval only once:

    var process;
    
    function func(){
        console.log('just for example');
    }
    
    window.addEventListener("keydown", (e)=>{
        if(e.key === "f") process ??= setInterval(func, 100);
    });
    
    window.addEventListener("keyup", (e)=>{
        if(e.key === "f") clearInterval(process), process = null;
    });
    Login or Signup to reply.
  2. You can remove the keydown event listener when the key is pressed, and then add it again when the key is released. As was already mentioned in the comments, this technique will prevent the creation of multiple interval timers due to repeated keydown events being fired for a single held key.

    This tool can be used to visualize keyboard events:

    https://w3c.github.io/uievents/tools/key-event-viewer.html (source code here)

    let intervalTimerId;
    
    function logTimestamp() {
      console.log(performance.now());
    }
    
    function handleKeyDown(ev) {
      if (ev.key === "f") {
        window.removeEventListener("keydown", handleKeyDown);
        logTimestamp(); // Invoke without initial delay if desired
        intervalTimerId = setInterval(logTimestamp, 100);
      }
    }
    
    function handleKeyUp(ev) {
      if (ev.key === "f") {
        clearInterval(intervalTimerId);
        window.addEventListener("keydown", handleKeyDown);
      }
    }
    
    window.addEventListener("keydown", handleKeyDown);
    window.addEventListener("keyup", handleKeyUp);
    Login or Signup to reply.
  3. Using ??= or clearing the interval is perfectly fine and elegant, but if the user releases the "f" key fast enough, the function won’t be called because the interval will be cleared.

    Instead, you might consider doing this with setTimeout instead of setInterval. With the following code example, when the user presses the "f" key, even if they let it go within 100 milliseconds, the function will still execute.

    A quick explanation of the code is that when the user presses "f", a setTimeout is initialized that will call the function. If the "f" key is still pressed when the function is called, the timeout is reset.

    const update_interval = 100; //ms
    const update_key = "f";
    
    function func() {
      console.log("This is where you put your functionality.");
    }
    
    const timeout_func = () => {
      if (activation_key_pressed) {
        setTimeout(timeout_func, update_interval);
      }
      func();
    }
    
    let activation_key_pressed = false;
    window.onkeydown = (e) => {
      //Call the timeout if the f key was NOT already pressed but IS pressed now.
      //The timeout will call itself again if needed.
      if (!activation_key_pressed && e.key == update_key) {
        setTimeout(timeout_func, update_interval);
      }
      if (e.key == update_key) activation_key_pressed = true;
    }
    window.onkeyup = (e) => {
      if (e.key == update_key) activation_key_pressed = false;
    }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search