[英]Cross-browser way to get automatically repeating keydown events when key is held down
Using Javascript / jQuery, how can I get automatically repeating keydown events, or equivalent, when someone holds down a key? 使用Javascript / jQuery,当有人按住某个键时,如何自动重复按下键事件或等效操作?
What I actually want is to be able to check whether a key is down, but from other questions here it looks like that's not possible. 我真正想要的是能够检查某个键是否按下,但是从这里的其他问题来看,这似乎是不可能的。 The suggested workaround seems to be recording keydown and keyup events and then assuming the key is down if a keydown event has been recorded and no subsequent keyup.
建议的解决方法似乎是记录keydown和keyup事件,然后如果已记录keydown事件并且没有后续的keyup,则假定该键已关闭。
That solution runs into a problem in my case. 在我看来,该解决方案遇到了问题。 I am designing an online experiment.
我正在设计一个在线实验。 The user is supposed to hold down the "T" key for the entire experiment, never letting it up.
用户应在整个实验过程中按住“ T”键,不要松开。 The experiment consists of multiple trials and each trial has no access to information recorded by the previous trials.
该实验包含多个试验,每个试验都无法访问先前试验记录的信息。 So, trial 1 could record keydown for T, but trial 2 wouldn't have access to that record and thus wouldn't know whether T was down or not.
因此,试验1可以记录T的密钥按下,但是试验2无法访问该记录,因此不知道T是否被按下。
Now, if holding down the T key would produce automatically repeating keydown events for T, I would have no problem because trial 2 would just catch the next keydown event for T to come along. 现在,如果按住T键会自动为T产生重复的按键事件,那么我将没有问题,因为试验2只会捕获下一个按键事件以使T出现。 But it looks like I don't get automatically repeating keydown events from holding the key down, at least in Firefox.
但是,看来至少在Firefox中,我不会通过按住键来自动重复按键事件。 From what I can see it seems there is variation in the way different browsers handle holding a key down.
从我所看到的情况来看,不同的浏览器处理按下键的方式似乎有所不同。 What is a good cross-browser way to solve my problem?
什么是跨浏览器解决我的问题的好方法?
By the way, if it matters, I also need to be able to detect keyup and keydown events for other keys while all this is going on. 顺便说一句,如果这很重要,那么在进行所有这些操作的同时,我还需要能够检测其他键的keyup和keydown事件。
EDIT: after reading some of the comments I went back and verified that I do indeed get repeating keydown events under ordinary circumstances. 编辑:阅读了一些评论后,我回过头来验证我确实确实在通常情况下会重复发生键盘按下事件。 But I really don't get them in the specific situation in which I need them.
但是我真的没有在需要它们的特定情况下使用它们。 I've got some simple code which I think isolates the issue:
我有一些简单的代码,我认为可以解决这个问题:
<!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 a key and hold it down, then release, then press again, the behavior is as expected, ie there is a counter which increments while the key is held down, disappears when it's released, and then starts incrementing again when it's pressed again. 如果按下某个键并按住不放,然后松开,然后再次按下,则行为符合预期,即,有一个计数器,按住该键时该计数器增加,释放该键时消失,然后按下该键再次开始增加计数再次。
But if you press TWO keys down, then release ONE, I would have thought that the other (not released) key would continue sending keydown events so that the counter would (after resetting) continue incrementing. 但是,如果您按下两个键,然后释放一个,我会认为另一个(未释放)键将继续发送按键事件,以便计数器(在重置之后)继续递增。 In fact, that doesn't happen.
实际上,这不会发生。 Any idea why and how to make it happen?
知道为什么以及如何实现它吗?
In the browsers I tried this in, I got repeated keydown events when holding a typeable key down. 在我尝试使用的浏览器中,按住可键入的键时,重复出现了键按下事件。 I don't know if this is a problem you actually need to solve.
我不知道这是否是您实际上需要解决的问题。
But, if you did think you need to solve it OR if you want to control the repeat-rate yourself, you could do it like this: 但是,如果您确实认为需要解决此问题,或者如果您想自己控制重复率,则可以执行以下操作:
Working demo here: http://jsfiddle.net/jfriend00/XbZYs/ 此处的工作演示: 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 a key to auto-repeat forever until it is raised, even if other keys are pressed and released in the meantime and you want those other keys to do their own auto-repeating, then the OS does not ipmlement that behavior so you would have to implement it yourself. 如果您希望某个键在弹出之前一直永久自动重复,即使同时按下并释放了其他键,并且您希望这些其他键执行自己的自动重复操作,则操作系统也不会执行该操作,所以您将不得不自己实施。 You can do something like this which calls a callback function for every key repeat event:
您可以执行以下操作,为每个键重复事件调用一个回调函数:
Working demo: http://jsfiddle.net/jfriend00/aD3Eg/ 工作演示: 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 of these manufactured auto-repeat events and passed the key that is auto-repeating. 对所有这些制造的自动重复事件都调用repeatCallback函数,并传递了自动重复的密钥。
看一下这个jQuery插件: fastKeys我认为,这就是您想要/需要的...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.