Deshabilitar el desplazamiento de la tecla de flecha en el navegador de los usuarios


87

Estoy haciendo un juego usando canvas y javascript.

Cuando la página es más larga que la pantalla (comentarios, etc.), al presionar la flecha hacia abajo, la página se desplaza hacia abajo y hace que el juego sea imposible de jugar.

¿Qué puedo hacer para evitar que la ventana se desplace cuando el jugador solo quiere bajar?

Supongo que con los juegos de Java, y demás, esto no es un problema, siempre que el usuario haga clic en el juego.

Probé la solución de: Cómo deshabilitar el desplazamiento de página en FF con las teclas de flecha , pero no pude hacer que funcione.

Respuestas:


164

Resumen

Simplemente evite la acción predeterminada del navegador:

window.addEventListener("keydown", function(e) {
    // space and arrow keys
    if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
        e.preventDefault();
    }
}, false);

Respuesta original

Usé la siguiente función en mi propio juego:

var keys = {};
window.addEventListener("keydown",
    function(e){
        keys[e.keyCode] = true;
        switch(e.keyCode){
            case 37: case 39: case 38:  case 40: // Arrow keys
            case 32: e.preventDefault(); break; // Space
            default: break; // do not block other keys
        }
    },
false);
window.addEventListener('keyup',
    function(e){
        keys[e.keyCode] = false;
    },
false);

La magia ocurre en e.preventDefault();. Esto bloqueará la acción predeterminada del evento, en este caso mover el punto de vista del navegador.

Si no necesita los estados del botón actual, simplemente puede soltar keysy descartar la acción predeterminada en las teclas de flecha:

var arrow_keys_handler = function(e) {
    switch(e.keyCode){
        case 37: case 39: case 38:  case 40: // Arrow keys
        case 32: e.preventDefault(); break; // Space
        default: break; // do not block other keys
    }
};
window.addEventListener("keydown", arrow_keys_handler, false);

Tenga en cuenta que este enfoque también le permite eliminar el controlador de eventos más adelante si necesita volver a habilitar el desplazamiento de la tecla de flecha:

window.removeEventListener("keydown", arrow_keys_handler, false);

Referencias


8
Realmente me gusta esta solución, pero no parece funcionar en chrome = /
Kaninepete

1
@Kaninepete: Hubo un error de sintaxis, lo usé en lC.keyslugar de keysen el oyente de teclado. Se corrigió esto y se probó en Firefox y Chrome. Tenga en cuenta que todos los cambios keysson opcionales, pero como está creando un juego ...
Zeta

en algunos navegadores más antiguos (móviles), parece que las teclas de flecha ni siquiera activan eventos clave ... :-(
Michael

1
Si hace esto, y tiene entradas de campo en su página web, entonces no podrá usar la barra espaciadora o las teclas de flecha para navegar por el texto. Gran inconveniente que encontré.
Entidad única

9
Tenga en cuenta que realmente necesita usar keydowny no keyup.
Ludder

4

Para facilitar el mantenimiento, adjuntaría el controlador de "bloqueo" en el elemento en sí (en su caso, el lienzo).

theCanvas.onkeydown = function (e) {
    if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
        e.view.event.preventDefault();
    }
}

¿Por qué no hacerlo simplemente window.event.preventDefault()? MDN dice:

window.eventes una propiedad patentada de Microsoft Internet Explorer que solo está disponible mientras se llama a un controlador de eventos DOM. Su valor es el objeto de evento que se está manejando actualmente.

Lecturas adicionales:


0

Probé diferentes formas de bloquear el desplazamiento cuando se presionan las teclas de flecha, tanto jQuery como Javascript nativo; todas funcionan bien en Firefox, pero no funcionan en versiones recientes de Chrome.
Incluso la {passive: false}propiedad explícita para window.addEventListener, que se recomienda como la única solución de trabajo, por ejemplo aquí .

Al final, después de muchos intentos, encontré una forma que funciona para mí tanto en Firefox como en Chrome:

window.addEventListener('keydown', (e) => {
    if (e.target.localName != 'input') {   // if you need to filter <input> elements
        switch (e.keyCode) {
            case 37: // left
            case 39: // right
                e.preventDefault();
                break;
            case 38: // up
            case 40: // down
                e.preventDefault();
                break;
            default:
                break;
        }
    }
}, {
    capture: true,   // this disables arrow key scrolling in modern Chrome
    passive: false   // this is optional, my code works without it
});

Cotización EventTarget.addEventListener()de MDN

opciones Opcional
   Un objeto de opciones especifica características sobre el detector de eventos. Las opciones disponibles son:

capture
   A Booleanque indica que los eventos de este tipo se enviarán a los registrados listenerantes de enviarse a cualquiera que EventTargetesté debajo de él en el árbol DOM.
once
   ...
pasivo
   A Booleanque, si es verdadero, indica que la función especificada por listenernunca llamará preventDefault(). Si un oyente pasivo llama preventDefault(), el agente de usuario no hará nada más que generar una advertencia en la consola. ...

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.