Ответ 1
Вместо того, чтобы пытаться реагировать непосредственно на событие keydown, я предлагаю вам использовать события keydown и keyup для поддержания списка ключей, которые в настоящее время недоступны. Затем реализуйте "игровой цикл", который проверяет каждые x миллисекунд, какие ключи опущены, и соответственно обновлять дисплей.
var keyState = {};
window.addEventListener('keydown',function(e){
keyState[e.keyCode || e.which] = true;
},true);
window.addEventListener('keyup',function(e){
keyState[e.keyCode || e.which] = false;
},true);
x = 100;
function gameLoop() {
if (keyState[37] || keyState[65]){
x -= 1;
}
if (keyState[39] || keyState[68]){
x += 1;
}
// redraw/reposition your object here
// also redraw/animate any objects not controlled by the user
setTimeout(gameLoop, 10);
}
gameLoop();
Вы заметите, что это позволяет вам обрабатывать сразу несколько ключей, например, если пользователь нажимает стрелки влево и вверх вместе, а проблема задержки между последующими событиями смены ключа при удерживании клавиши уходит, поскольку все вы действительно заботится о том, произошел ли запуск клавиатуры.
Я понимаю, что вы не можете реализовывать игру, но эта концепция "игрового цикла" должна работать для вас, как показано в этой простой демонстрации: http://jsfiddle.net/nnnnnn/gedk6/