繁体   English   中英

跨浏览器的方式,在按住键时自动重复重复按下事件

[英]Cross-browser way to get automatically repeating keydown events when key is held down

使用Javascript / jQuery,当有人按住某个键时,如何自动重复按下键事件或等效操作?

我真正想要的是能够检查某个键是否按下,但是从这里的其他问题来看,这似乎是不可能的。 建议的解决方法似乎是记录keydown和keyup事件,然后如果已记录keydown事件并且没有后续的keyup,则假定该键已关闭。

在我看来,该解决方案遇到了问题。 我正在设计一个在线实验。 用户应在整个实验过程中按住“ T”键,不要松开。 该实验包含多个试验,每个试验都无法访问先前试验记录的信息。 因此,试验1可以记录T的密钥按下,但是试验2无法访问该记录,因此不知道T是否被按下。

现在,如果按住T键会自动为T产生重复的按键事件,那么我将没有问题,因为试验2只会捕获下一个按键事件以使T出现。 但是,看来至少在Firefox中,我不会通过按住键来自动重复按键事件。 从我所看到的情况来看,不同的浏览器处理按下键的方式似乎有所不同。 什么是跨浏览器解决我的问题的好方法?

顺便说一句,如果这很重要,那么在进行所有这些操作的同时,我还需要能够检测其他键的keyup和keydown事件。

编辑:阅读了一些评论后,我回过头来验证我确实确实在通常情况下会重复发生键盘按下事件。 但是我真的没有在需要它们的特定情况下使用它们。 我有一些简单的代码,我认为可以解决这个问题:

<!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>

如果按下某个键并按住不放,然后松开,然后再次按下,则行为符合预期,即,有一个计数器,按住该键时该计数器增加,释放该键时消失,然后按下该键再次开始增加计数再次。

但是,如果您按下两个键,然后释放一个,我会认为另一个(未释放)键将继续发送按键事件,以便计数器(在重置之后)继续递增。 实际上,这不会发生。 知道为什么以及如何实现它吗?

在我尝试使用的浏览器中,按住可键入的键时,重复出现了键按下事件。 我不知道这是否是您实际上需要解决的问题。

但是,如果您确实认为需要解决此问题,或者如果您想自己控制重复率,则可以执行以下操作:

  1. 捕获事件以进行击键和击键。
  2. 按下按键时,设置一个间隔计时器,该计时器会触发,但是您经常想知道按键仍在按下状态。
  3. 在键入该键时,停止间隔计时器。
  4. 只要按住该键,您将以跨浏览器的方式反复收到通知。

此处的工作演示: 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;
    }
});

如果您希望某个键在弹出之前一直永久自动重复,即使同时按下并释放了其他键,并且您希望这些其他键执行自己的自动重复操作,则操作系统也不会执行该操作,所以您将不得不自己实施。 您可以执行以下操作,为每个键重复事件调用一个回调函数:

工作演示: 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];
    }
});
​

对所有这些制造的自动重复事件都调用repeatCallback函数,并传递了自动重复的密钥。

看一下这个jQuery插件: fastKeys我认为,这就是您想要/需要的...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM