2012-05-05 11 views
5

Situación: Tengo un controlador keydown con un switch para lo que se pulsa la tecla cosas, bastante estándar, pero cuando cualquier tecla se mantiene pulsada la keydown desencadena el evento en varias ocasiones (en lugar de sólo una vez cuando la tecla está realmente presionada).Fuerza keydown para disparar sólo una vez por keyCode

Por qué es un problema: Quiero mantener al oyente keydown activo, es decir, ser capaz de detectar más de una tecla que se presiona a la vez, pero sólo tienen el fuego una vez por evento keydown. Me gustaría hacer algo en el keyup para ese keyCode basado en el tiempo entre abajo y arriba, pero ese tiempo se está estropeando debido a los disparos múltiples.

Lo que he tratado: Actualmente estoy manteniendo una lista de keyCodes que están abajo, y la comprobación frente a los de mi manejador keydown para mantener el comportamiento predeterminado suceda si el keyCode está en mi lista. Sin embargo, el evento todavía se activa muy a menudo y me preocupa la eficiencia/elegancia de esta solución.

La pregunta real: ¿Hay una buena manera de limitar la activación del evento keydown a solo cuando la llave se empuja hacia abajo físicamente, o para escuchar sólo para códigos de teclas específicas?

+0

"es decir, ser capaz de detectar más de una tecla presionada a la vez" Eso significa qué? – epascarello

+0

Por ejemplo, mantenga presionada la tecla 'y', luego presione y mantenga presionada la tecla 'o'. Esto excluye la solución de eliminar el evento de colocación de tecla y agregarlo nuevamente después de la tecla. –

Respuesta

8

En el manejador de teclas, compruebe si la tecla es la misma que la última tecla manejada. Si lo fue, salga temprano. En keyup, olvida la última clave manejada.

Por ejemplo:

var lastEvent; 
var heldKeys = {}; 

window.onkeydown = function(event) { 
    if (lastEvent && lastEvent.keyCode == event.keyCode) { 
     return; 
    } 
    lastEvent = event; 
    heldKeys[event.keyCode] = true; 
}; 

window.onkeyup = function(event) { 
    lastEvent = null; 
    delete heldKeys[event.keyCode]; 
};​ 

Demo here (haga clic en el panel "Resultado" y pulsa las teclas).

0

Defina un valor booleano para registrar si se presiona la tecla. Establézcalo en verdadero en el evento de tecla abajo. Haga que su ciclo principal verifique si el valor es verdadero y maneje el evento, y establezca la tecla presionada en falso. Tener otro booleano para grabar si se suelta la tecla (inicialmente falso). Si el evento de activación se activa, establézcalo en liberado. Establezca solo el valor de la tecla presionada en verdadero (en el evento de tecla abajo) si el valor "liberado" también es verdadero.

+0

Esta es una muy buena respuesta. Lo único que probablemente agregue es que definiría una matriz de objetos para almacenar los booleanos en cada código de tecla mientras está presionado, y en ese objeto sería [{"43": true}, ...] y luego simplemente elimine ese código clave como se sugiere arriba. – LocalPCGuy

+0

Esto es realmente lo que estoy haciendo ahora, lo siento si no estaba claro. Mantengo los códigos de tecla 'abajo' almacenados y eliminándolos en la tecla. Me interesan las alternativas que puedan ser más eficientes que la comprobación varias veces por segundo en mi lista de códigos clave. –

0

Aquí es un ejemplo de lo que creo que quiere lograr: jsFiddle Example

Actualmente las combinaciones CTRL + B es el único que los thats detectado. Simplemente presione algunos números para obtener un registro de las actividades. Cuando la tecla ya está presionada, detecta la acción de retención.

Cuestiones relacionadas