onkeydown事件只在十分之一秒执行

时间:2012-12-22 21:14:45

标签: javascript settimeout onkeypress

所以我在网格周围移动了一个小方块,但是当我执行onkeydown事件时,我的方块移动非常快。我只希望它每10秒执行一次,这样我的小方块就不会碰到一把剪刀。但是当我尝试一个setTimeout函数时,它只会在第一次keydown超时,然后继续快速执行,当你释放密钥时它仍在执行以赶上。这对我的小广场来说非常不安全。任何帮助将不胜感激。

这是没有setTimeout函数的代码,只是因为我觉得这不是正确的方法:

function checkArrowKeys(e){
    var arrs= [], key= window.event? event.keyCode: e.keyCode;
    arrs[37]= 'left';
    arrs[38]= 'up';
    arrs[39]= 'right';
    arrs[40]= 'down';
    if(arrs[key]){
        transition(arrs[key]);
    }
}
document.onkeydown=checkArrowKeys;

2 个答案:

答案 0 :(得分:1)

如果没有发生预设延迟,您可以通过退出该功能来停止执行转换。

var bWait=false;
function checkArrowKeys(e){
    if (bWait) return;
    var arrs= [], key= window.event? event.keyCode: e.keyCode;
    arrs[37]= 'left';
    arrs[38]= 'up';
    arrs[39]= 'right';
    arrs[40]= 'down';
    if(arrs[key]){
        transition(arrs[key]);
    }
    bWait=true; //wait for 10 milliseconds
    window.setTimeout("bWait=false;",10);
}
document.onkeydown=checkArrowKeys;

您怎么看?

答案 1 :(得分:1)

键盘响应可能会变得异常复杂。通常你不想注意每个被触发的keydown事件,因为这取决于用户的键盘和设置;例如一个事件最初触发然后暂停后,一个快速流被激发。当用户同时按下两个键时,还有一个问题。

以下代码通过具有单独的更新功能将键盘响应与动画分开。按下新的箭头键后,方块最初移动1步(设置为5px),然后连续移动100ms直到释放该键。

Fiddle

var directions = [],
    lastPressTime, stepped, ti, frameRate = 30,
    squareSpeed = 5, stepTime = 100;

function update() {
    var x, y, d = directions[directions.length - 1],
        square = document.getElementById('square');
    if (!d) {
        return;
    }
    if (new Date().getTime() < lastPressTime + stepTime) {
        if (stepped) { // already stepped and <100ms has passed
            return;    // so do nothing
        }
        else {
            stepped = true;
        }
    }
    x = square.offsetLeft;
    y = square.offsetTop;
    if (d == 'left') {
        x -= squareSpeed;
    }
    else if (d == 'right') {
        x += squareSpeed;
    }
    else if (d == 'up') {
        y -= squareSpeed;
    }
    else if (d == 'down') {
        y += squareSpeed;
    }
    square.style.left = x + 'px';
    square.style.top = y + 'px';
}
function checkArrowKeys(e) {
    var arrs = [],
        key = window.event ? event.keyCode : e.keyCode;
    arrs[37] = 'left';
    arrs[38] = 'up';
    arrs[39] = 'right';
    arrs[40] = 'down';
    if (arrs[key]) {
        return arrs[key];
    }
}
document.onkeydown = function(e) {
    var d = checkArrowKeys(e);
    if (d) {
        // Key not already pressed; add it to array 
        // of directions and step forward
        if (directions.indexOf(d) === -1) {
            directions.push(d);
            lastPressTime = new Date().getTime();
            stepped = false;
        }
        if (!ti) {
            ti = setInterval(update, 1000 / frameRate);
        }
    }
};

document.onkeyup = function(e) {
    var d = checkArrowKeys(e),
        i;
    if (d) {
        i = directions.indexOf(d);
        // remove this direction from the array of directions
        if (i > -1) {
            directions = 
                directions.slice(0, i).concat(directions.slice(i + 1));
        }
        // if no keys are down then stop updating
        if (directions.length === 0) {
            clearInterval(ti);
            ti = null;
        }
    }
};