Désactiver le défilement des touches fléchées dans le navigateur des utilisateurs

87

Je crée un jeu en utilisant canvas et javascript.

Lorsque la page est plus longue que l'écran (commentaires, etc.), appuyer sur la flèche vers le bas fait défiler la page vers le bas et rend le jeu impossible à jouer.

Que puis-je faire pour empêcher la fenêtre de défiler lorsque le joueur veut simplement descendre?

Je suppose qu'avec les jeux Java, et autres, ce n'est pas un problème, tant que l'utilisateur clique sur le jeu.

J'ai essayé la solution de: Comment désactiver le défilement de page dans FF avec les touches fléchées , mais je ne pouvais pas le faire fonctionner.

Kaninepete
la source

Réponses:

164

Sommaire

Empêchez simplement l' action du navigateur par défaut :

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

Réponse originale

J'ai utilisé la fonction suivante dans mon propre jeu:

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 magie opère e.preventDefault();. Cela bloquera l'action par défaut de l'événement, dans ce cas en déplaçant le point de vue du navigateur.

Si vous n'avez pas besoin des états de bouton actuels, vous pouvez simplement supprimer keyset simplement supprimer l'action par défaut sur les touches fléchées:

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);

Notez que cette approche vous permet également de supprimer le gestionnaire d'événements ultérieurement si vous devez réactiver le défilement des touches fléchées:

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

Références

Zeta
la source
8
J'aime vraiment cette solution, mais elle ne semble pas fonctionner dans chrome = /
Kaninepete
1
@Kaninepete: Il y a eu une erreur de syntaxe, j'ai utilisé à la lC.keysplace de keysl'écouteur keyup. Corrigé et testé dans Firefox et Chrome. Notez que tous les changements keyssont facultatifs, mais puisque vous construisez un jeu ...
Zeta
dans certains navigateurs (mobiles) plus anciens, il semble que les touches fléchées ne déclenchent même pas les événements clés ... :-(
Michael
1
Si vous faites cela et que vous avez des entrées de champ sur votre page Web, vous ne pourrez pas utiliser la barre d'espace ou les touches fléchées pour naviguer dans le texte. Gros inconvénient que j'ai trouvé.
Single Entity
9
Notez que vous devez vraiment utiliser keydownet non keyup.
Ludder
4

Pour la maintenabilité, j'attacherais le gestionnaire "bloquant" sur l'élément lui-même (dans votre cas, le canevas).

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

Pourquoi ne pas simplement faire window.event.preventDefault()? MDN déclare:

window.eventest une propriété Microsoft Internet Explorer propriétaire qui n'est disponible que lorsqu'un gestionnaire d'événements DOM est appelé. Sa valeur est l'objet Event en cours de traitement.

Lectures complémentaires:

Yom S.
la source
0

J'ai essayé différentes façons de bloquer le défilement lorsque vous appuyez sur les touches fléchées, à la fois jQuery et Javascript natif - ils fonctionnent tous très bien dans Firefox, mais ne fonctionnent pas dans les versions récentes de Chrome.
Même la {passive: false}propriété explicite pour window.addEventListener, qui est recommandée comme seule solution de travail, par exemple ici .

En fin de compte, après de nombreux essais, j'ai trouvé un moyen qui fonctionne pour moi à la fois dans Firefox et 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
});

Devis EventTarget.addEventListener()de MDN

options Facultatif
   Un objet options spécifie les caractéristiques de l'écouteur d'événements. Les options disponibles sont:

capture
   A Booleanindiquant que les événements de ce type seront envoyés à l'enregistré listeneravant d'être distribués à tout EventTargetce qui se trouve en dessous dans l'arborescence DOM.
once
   ...
passif
   A Booleanqui, s'il est vrai, indique que la fonction spécifiée par listenerne sera jamais appelée preventDefault(). Si un auditeur passif appelle preventDefault(), l'agent utilisateur ne fera rien d'autre que de générer un avertissement de console. ...

Almaceleste
la source