Cross-browser way to automatically repeat events when a key is opened when a key is pressed

Using Javascript / jQuery, how can I automatically repeat keydown events or their equivalents when someone holds a key?

What I really want is to check if the key is locked, but from other questions here it seems that this is not possible. The proposed solution to the problem is to record keypress and keyup events, and then, provided that the key does not work if the keydown event was recorded and subsequent activation of the keyboard.

In my case, the problem is resolved. I am developing an online experiment. It is assumed that the user must hold down the "T" key for the entire experiment, never release it. An experiment consists of several tests, and each test does not have access to the information recorded in previous tests. Thus, trial version 1 can record keydown for T, but trial version 2 will not have access to this record and, therefore, will not know whether T was down or not.

Now, if holding down the T key would automatically repeat the keydown events for T, I would not have a problem because trial version 2 just caught the next keydown event so that T appears. But it looks like I am not getting auto-repeat of keydown events by holding down the key, at least in Firefox. From what I see, it seems that there is a difference in how different browsers handle keystrokes. What is a good cross-browser way to solve my problem?

By the way, if that matters, I also need to be able to detect keyup and keydown events for other keys while this all happens.

EDIT: after reading some comments, I came back and confirmed that I was really repeating key change events under normal circumstances. But I really do not understand them in the specific situation in which I need them. I have simple code that I think isolates the problem:

<!DOCTYPE html> <html> <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script> </head> <body> <div id="target"></div> </body> <script type="text/javascript"> var i; function foo() { i++; $('#target').html(i); } function doTrial() { // do trial i=0; $(document).keydown(foo); $(document).keyup(endTrial); } function endTrial() { // end trial $('#target').html(''); $(document).unbind('keydown',foo); $(document).unbind('keyup',endTrial); doTrial(); } doTrial(); </script> </html> 

If you press and hold the key, then release and then press again, the behavior will be as expected, i.e. there will be a counter that increases while holding the key, disappears when it is released, and then starts to increase again when it is pressed again.

But if you press TWO keys down and then release ONE, I would think that another (not issued) key would continue to send blocking events so that the counter (after reset) continued to increase. This does not actually happen. Any idea why and how to do this?

+4
source share
2 answers

In the browsers in which I tried this, I received repeated key change events while holding down the enter key. I do not know if this is really a problem that you really need to solve.

But if you thought that you need to solve it OR if you want to control the repeat speed yourself, you can do it as follows:

  • Capture events to lock keys and keyboards.
  • When you start the keyboard, set the timer at intervals that often fire when you want to know that the key is still off.
  • On the keyboard for this key, stop the time interval.
  • You will receive repeated notification with the cross browser as long as the key is held down.

Working demo here: http://jsfiddle.net/jfriend00/XbZYs/

 var downTimer; var lastKey; $(document.body).keydown(function(e) { // if not still the same key, stop the timer if (e.which !== lastKey) { if (downTimer) { clearInterval(downTimer); downTimer = null; } } // remember previous key lastKey = e.which; if (!downTimer) { // start timer downTimer = setInterval(function() { $("#result").append("+"); }, 125); } }).keyup(function(e) { // stop timer if (downTimer) { clearInterval(downTimer); downTimer = null; lastKey = 0; } }); 

If you want the key to repeat automatically until it is raised, even if other keys are pressed and released at that time, and you want these other keys to perform their own auto-repeat, then the OS does not use ipmlement, so you have to implement it yourself. You can do something like this that calls the callback function for each key repetition event:

Working demo: http://jsfiddle.net/jfriend00/aD3Eg/

 // this is called for every manufactured repeat event // the frequency of the repeat event is determined by the time value set // on setInterval() below function repeatCallback(key) { $("#result").append(key + " "); } var repeatState = {}; $(document.body).keydown(function(e) { var key = e.which; // if no time yet for this key, then start one if (!repeatState[key]) { // make copy of key code because `e` gets reused // by other events in IE so it won't be preserved repeatState[key] = setInterval(function() { repeatCallback(key); }, 125); } else { // nothing really to do here // The key was pressed, but there is already a timer // firing for it } }).keyup(function(e) { // if we have a timer for this key, then stop it // and delete it from the repeatState object var key = e.which; var timer = repeatState[key]; if (timer) { clearInterval(timer); delete repeatState[key]; } });​ 

The repeatCallback function is called for all these generated auto-repeat events and passes a key that automatically repeats.

+6
source

Take a look at this jQuery plugin: fastKeys I think this is what you need / need ...

0
source

All Articles