Скрипка: http://jsfiddle.net/ATUEx/
Создайте временный кеш для запоминания ваших нажатий клавиш.
Реализация обработки двух ключей будет выглядеть следующим образом:
<keydown>
- Очистить предыдущий тайм-аут.
- Проверьте, был ли кеширован код клавиши или нет.
Если да, и допустимая комбинация:
-
Удалить все кэшированные коды клавиш
-
Выполнить функцию для этой комбинации
еще
-
Удалить все кэшированные коды клавиш
-
Сохранить новый код ключа
-
Установите время для сброса кодов клавиш (см. Ниже) с разумной задержкой
- Повтор 1
Разумная задержка: Экспериментируйте, чтобы узнать, какое время ожидания достаточно для вас. Если задержка слишком мала, следующее инициированное событие не найдет ранее введенный код клавиши.
Когда задержка слишком велика, нажатия клавиш будут складываться, когда вы этого не хотите.
код
Я создал эффективную функцию, помня ваш код. Вы должны быть в состоянии реализовать это очень легко.
(function(){ //Anonymous function, no leaks
/* Change the next variable if necessary */
var timeout = 200; /* Timeout in milliseconds*/
var lastKeyCode = -1;
var timer = null;
function keyCheck(ev){
var keyCode = typeof ev.which != "undefined" ? ev.which : event.keyCode;
/* An alternative way to check keyCodes:
* if(keyCode >= 37 && keyCode <= 40) ..*/
/*37=Left 38=Up 39=Right 40=Down */
if([37, 38, 39, 40].indexOf(keyCode) != -1){
/* lastKeyCode == -1 = no saved key
Difference betwene keyCodes == opposite keys = no possible combi*/
if(lastKeyCode == -1 || Math.abs(lastKeyCode - keyCode) == 2){
refresh();
lastKeyCode = keyCode;
} else if(lastKeyCode == keyCode){
clear([lastKeyCode]);
} else {
/* lastKeyCode != -1 && keyCode != lastKeyCode
and no opposite key = possible combi*/
clear([lastKeyCode, keyCode]);
lastKeyCode = -1
}
ev.preventDefault(); //Stop default behaviour
ev.stopPropagation(); //Other event listeners won't get the event
}
/* Functions used above, grouped together for code readability */
function reset(){
keyCombi([lastKeyCode]);
lastKeyCode = -1;
}
function clear(array_keys){
clearTimeout(timer);
keyCombi(array_keys);
}
function refresh(){
clearTimeout(timer);
timer = setTimeout(reset, timeout);
}
}
var lastX = false;
var lastY = false;
function keyCombi(/*Array*/ keys){
/* Are the following keyCodes in array "keys"?*/
var left = keys.indexOf(37) != -1;
var up = keys.indexOf(38) != -1;
var right = keys.indexOf(39) != -1;
var down = keys.indexOf(40) != -1;
/* What direction? */
var x = left ? "negative" : right ? "positive" : false;
var y = up ? "negative" : down ? "positive" : false;
/* Are we heading to a different direction?*/
if(lastX != x || lastY != y) animation.move(x, y);
lastX = x;
lastY = y;
}
//Add event listener
var eventType = "keydown";window["on"+eventType] = keyCheck;
})();
В конце анонимной функции добавляется прослушиватель событий keydown
. Это событие вызывается только один раз (когда клавиша нажата). Когда вторая клавиша нажата достаточно быстро, код распознает два нажатия клавиши друг за другом и вызывает keyCombi()
.
Я разработал keyCombi
, чтобы быть умным, и вызывать animation.move(x,y)
только тогда, когда значения изменяются. Также я реализовал возможность работать с двумя направлениями одновременно.
Примечание : Я содержал функции в оболочке анонимной функции, поэтому переменные не определены в глобальной (window
) области. Если вам не нужна область видимости, не стесняйтесь удалить первую и последнюю строку.