Fiddle: http://jsfiddle.net/ATUEx/
Create a temporary cache to remember your strokes.
The implementation of the processing of the two keys will follow this pattern:
<keydown>
- Delete previous timeout.
- Check if a key code has been cached.
If yes, and a valid combination:
-
Delete all cached key codes
-
Execute function for this combination
yet
-
Delete all cached key codes
-
Save new key code
-
Set a timeout to clear key codes (see below) with a reasonable delay
- Repeat 1
Reasonable delay: an experiment to find out which timeout is enough for you. When the delay is too short, the next triggered event will not find the previously entered key code.
When the delay is too long, key strokes will flock when you don't want it.
the code
I created an efficient function by keeping your code in mind. You should be able to implement it very easily.
(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; })();
A keydown
event listener has been added at the end of the anonymous function. This event is fired only once (when the key is pressed). When the second key is pressed fast enough, the code recognizes two keystrokes one after another and calls keyCombi()
.
I designed keyCombi
to be intelligent and only call animation.move(x,y)
when the values ββchange. In addition, I realized the ability to use two directions at the same time.
Note I have included functions in the shell of anonymous functions, so the variables are not defined in the global ( window
) area. If you do not need a field of view, feel free to delete the first and last line.