2010-01-07 36 views
6

En Javascript, ¿cómo puedo saber si un usuario está presionando dos teclas al mismo tiempo?En Javascript, ¿cómo puedo saber si un usuario presiona dos teclas al mismo tiempo?

Por ejemplo, he dibujado un círculo en el medio de la pantalla. Quiero moverlo hacia arriba mientras el usuario mantiene presionada la flecha hacia arriba y hacia la derecha mientras el usuario mantiene presionada la flecha hacia la derecha. Esa parte funciona facilmente Si el usuario retiene las flechas hacia arriba y hacia la derecha, quiero mover el círculo en diagonal hacia arriba y hacia la derecha.

Parece que esto no es posible con el manejo de eventos de JavaScript básico, pero seguramente alguien ha descubierto una solución/hack/mejora.

+0

¿Cómo dibujó el círculo en el medio de la pantalla con el Javascript? Si usa algunas bibliotecas, especifíquelas, el manejo de las teclas se debe hacer dentro de esa biblioteca. – YOU

+0

Usé Raphael [raphaeljs.com], que es una biblioteca svg. No creo que proporcione ninguna funcionalidad clave de entrada. –

Respuesta

8

Esto es lo que hay que hacer conceptualmente (supongo que esto se llama pseudo código):

empezar con algo como esto:

var PIXEL_DELTA = 10; // Distance to move in pixels 

var leftPressed = 0, 
    upPressed = 0, 
    downPressed = 0, 
    rightPressed = 0; 

luego en cada keydown caso, la prueba si la clave presionado es left, up, etc. y cambia su variable de 0 a PIXEL_DELTA.

En cada evento keyup, ejecute la misma prueba y devuelva la variable correcta a 0.

Luego, en el código de movimiento (código real): (Este código adaptado de ejemplo impresionante de la Media Luna fresca):

function move() { 
    var dot = document.getElementById('dot'), 
     deltaX = rightPressed - leftPressed, 
     deltaY = downPressed - upPressed; 

    if(deltaX) { 
    dot.style.left = (parseInt(dot.style.left, 10) || 0) + deltaX + 'px'; 
    } 

    if (deltaY) { 
    dot.style.top = (parseInt(dot.style.top, 10) || 0) + deltaY + 'px'; 
    } 
} 

El navegador (debería) disparar un separada caso keydown/keyup para cada tecla, incluso si se presionan "simultáneamente".

Ejemplo de trabajo

Media Luna Fresh armar un full example on JSBin. Asegúrese de visitar el editable version para jugar con el código.

+3

Sí, pero usaría números y alternaría entre '0' (su falso) y' n' (su verdadero), donde 'n' es el delta del píxel. El código móvil no necesitaría probar los booleanos, pero simplemente haga una aritmética básica. Código no psuedo: http://jsbin.com/iloxi –

+0

@Crescent, me encanta.Actualizaré mi respuesta si no quieres publicar la tuya, pero deberías hacerlo ya que es una gran solución y tienes una demostración en funcionamiento. –

+0

@DN: sé mi invitado, lo has clavado. –

1

Los eventos del teclado Javascript se activan al presionar las teclas y al hacer clic, pero no contienen la información adicional de máscara clave para determinar si se presionan otras teclas al mismo tiempo.

2

Tal vez pueda hacerlo haciendo un seguimiento de los eventos de keydown y keyup para cada tecla y sabrá si se están manteniendo dos claves al mismo tiempo.

Muestra pseudo-código:

var keydown = {}; 

function onkeydown(event) { 
    keydown[event.key] = true; 
} 

function onkeyup(event) { 
    keydown[event.key] = false; 
} 

// in some function at some other places 

if (keydown['up'] && keydown['right']) { 
    move_diagonal('up', 'right'); 
} 
elseif (keydown['up'] && keydown['left']) { 
    move_diagonal('up', 'left'); 
} 
elseif .. blah blah 
4

Javascript onKeyDown y onkeyup eventos. Usted puede jugar un poco con la tecla de flecha hacia la izquierda, y tocar otro poco para la flecha hacia arriba. En keyup, toque el bit respectivo hacia atrás.

var leftPressed, 
    upPressed, 
    rightPressed, 
    downPressed; 

var milli = 100; 

window.addEventListener('onkeydown', function(e) { 
    switch(e.keycode) { 
     case 37: //left 
      leftPressed = true; 
     case 38: //up 
      upPressed = true; 
     case 39: //right 
      rightPressed = true; 
     case 40: //down 
      downPressed = true; 
     default: 
      break; 
    } 
}); 

window.addEventListener('onkeyup', function(e) { 
    switch(e.keycode) { 
     case 37: //left 
      leftPressed = false; 
     case 38: //up 
      upPressed = false; 
     case 39: //right 
      rightPressed = false; 
     case 40: //down 
      downPressed = false; 
     default: 
      break; 
    } 

}); 

function moveCircle() { 
    if(leftPressed && !rightPressed) { 
     // move left 
    } 
    if(rightPressed && !leftPressed) { 
     // move right 
    } 
    if(upPressed && !downPressed) { 
     // move up 
    } 
    if(downPressed && !upPressed) { 
     // move down 
    } 
} 

setInterval(moveCircle, milli); 
+2

Creo que la idea general que tiene funcionará, pero no creo que este código sí lo haga. El mensaje de tecla abajo se envía repetidamente si se mantiene presionada una tecla. Y no quiero volver a mover el círculo en Keyup. Quiero dejar de moverlo. –

+0

Tienes razón, podría haber confundido onkeydown y onkeypress. Sin embargo, la parte onkeyup es dejar de moverse en la dirección. En la esquina inferior izquierda, dx se convierte en -1. Al levantarlo, dx +1 vuelve a ser 0. – seanmonstar

+0

@seanmonstar: Aun así, tienes un problema con el evento Keydown que se autorepeta. –

Cuestiones relacionadas