2

In JQuery I know that there is a function called keydown, but this does allow me to set a timeout each time the callback is called.

$(document).keydown(() => {
  //do stuff
});

The //do stuff calls too fast each time. I want to call this every 500 milliseconds while the user is holding a key. Is there any way to do this?

  • 1
    No it does not because I want to trigger the function every x seconds –  Jan 12 '20 at 02:15
  • It's know as throttling/debouncing, this is what are searching for https://stackoverflow.com/a/7373040 – Vinay Jan 12 '20 at 03:13

4 Answers4

4

I'm not sure if this is best approach, but this would be solve your problem

var pressedAt = 0
var timeStep = 500 // 500 ms

function checkKey(e) {
 if(pressedAt == 0) {
  pressedAt = Date.now() 
 }
 if (Date.now() - pressedAt >= timeStep) {
  console.log("Key Pressed");
  pressedAt = 0
 }
}

document.addEventListener("keydown", checkKey);
document.addEventListener("keyup", function(){
  pressedAt = 0
  console.clear()
});
Ahmet Zeybek
  • 1,196
  • 1
  • 13
  • 24
1

Is this what you are looking for? (I used a button for this example)

const button = document.querySelector('#press');
let interval;

button.onmousedown = () => {
  interval = setInterval(() => {
    console.log('every 500ms');
  }, 500);
}

button.onmouseup = () => {
   clearInterval(interval);
}

When user pressed the button and keeps it pressed the message will be logged to the console every 500ms. When the user no longer presses the button, the console logging stops.

UPDATE: This approach is not correct for keydown events, only mouse. I believe @Ahmet Zeybek has the correct answer.

SciFiThief
  • 586
  • 5
  • 9
1

I'm not familiar with JQuery, but...

Here's a solution with a slightly different result than that of the other answers.

The 500ms timer is not dependent on the key presses.

let isAHeld = false;
$(document).keydown((event) => {
  if (event.key === 'a') {
    isAHeld = true;
  }
});
$(document).keyup((event) => {
  if (event.key === 'a') {
    isAHeld = false;
  }
});
$(document).ready(() => {
  setInterval(() => {
    const result = $("#result")[0];
    if (result && isAHeld) {
      result.innerHTML += " A!";
    }
  }, 500);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>Click here to give focus, then press and hold "a".</div>
<div id="result">Output:</div>
Stratubas
  • 2,939
  • 1
  • 13
  • 18
1

If you want to call an action each 500ms while a user holds a key try the following snippet.

Keep in mind that for some keys like "space", letters, etc. the keydown event will be called multiple times until you stop pressing the key but for other keys like "strg" or "cmd" the keydown event will be called only once. This approach should fit both cases.

var timer1 = null;
var time = 500;


$(document).on('keydown', function() {

  //console.log('keydown has been called');

  // init once, because for some keys (e.g. space, letters, etc.) 
  // this handler will be called consistently while you press the button.
  // some other buttons like "strg", "cmd", etc. will be called once only
  if (timer1 === null) {

    // now from exec each 500ms
    timer1 = setInterval(function() {

      $('body').append('<div>I will be called each 500ms</div>')
    }, time);
  }
});

$(document).on('keyup', function() {

  clearInterval(timer1);
  timer1 = null;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Click me to get focus and then press a key for 500ms or longer.</p>

Here the fiddle: https://jsfiddle.net/8Lzwupvo/

And a fiddle with an initial 500ms delay: https://jsfiddle.net/92mLx7kj/1/

sergej
  • 1,077
  • 1
  • 14
  • 20