所以我在网格周围移动了一个小方块,但是当我执行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;
答案 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;
}
}
};