Disabilita lo scorrimento dei tasti freccia nel browser degli utenti


87

Sto realizzando un gioco usando canvas e javascript.

Quando la pagina è più lunga dello schermo (commenti, ecc.), Premendo la freccia in basso si scorre la pagina verso il basso e si rende impossibile giocare al gioco.

Cosa posso fare per evitare che la finestra scorra quando il giocatore vuole solo spostarsi verso il basso?

Immagino che con i giochi Java e simili, questo non sia un problema, a condizione che l'utente faccia clic sul gioco.

Ho provato la soluzione da: Come disabilitare lo scorrimento della pagina in FF con i tasti freccia , ma non sono riuscito a farlo funzionare.

Risposte:


165

Sommario

Impedisci semplicemente l' azione del browser predefinito :

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

Risposta originale

Ho usato la seguente funzione nel mio gioco:

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 accade dentro e.preventDefault();. Questo bloccherà l'azione predefinita dell'evento, in questo caso spostando il punto di vista del browser.

Se non hai bisogno degli stati del pulsante corrente, puoi semplicemente rilasciare keyse scartare l'azione predefinita sui tasti freccia:

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

Tieni presente che questo approccio ti consente anche di rimuovere il gestore eventi in un secondo momento se devi riattivare lo scorrimento con i tasti freccia:

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

Riferimenti


8
Mi piace molto questa soluzione, ma non sembra funzionare in chrome = /
Kaninepete

1
@Kaninepete: si è verificato un errore di sintassi, che ho usato al lC.keysposto del keyslistener keyup. Risolto il problema e testato in Firefox e Chrome. Nota che tutte le modifiche a keyssono facoltative, ma poiché stai costruendo un gioco ...
Zeta

in alcuni browser meno recenti (mobili), sembra che i tasti freccia non attivino nemmeno gli eventi chiave ... :-(
Michael

1
Se lo fai e hai input di campo sulla tua pagina web, allora non sarai in grado di usare la barra spaziatrice oi tasti freccia per navigare nel testo. Grande svantaggio che ho trovato.
Entità Unica

9
Nota che hai davvero bisogno di usare keydowne non keyup.
Ludder

4

Per la manutenibilità, collegherei il gestore di "blocco" all'elemento stesso (nel tuo caso, la tela).

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

Perché non farlo semplicemente window.event.preventDefault()? MDN afferma:

window.eventè una proprietà proprietaria di Microsoft Internet Explorer disponibile solo durante la chiamata di un gestore di eventi DOM. Il suo valore è l'oggetto Event attualmente gestito.

Ulteriori letture:


1

Ho provato diversi modi per bloccare lo scorrimento quando vengono premuti i tasti freccia, sia jQuery che Javascript nativo: funzionano tutti bene in Firefox, ma non funzionano nelle versioni recenti di Chrome.
Anche la {passive: false}proprietà esplicita per window.addEventListener, che è consigliata come unica soluzione funzionante, ad esempio qui .

Alla fine, dopo molti tentativi, ho trovato un modo che funziona per me sia in Firefox che in 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
});

Citazione per EventTarget.addEventListener()da MDN

opzioni Facoltativo
   Un oggetto opzioni specifica le caratteristiche del listener di eventi. Le opzioni disponibili sono:

cattura
   A Booleanche indica che gli eventi di questo tipo verranno inviati al registrato listenerprima di essere inviati a qualsiasi EventTargetsotto di esso nell'albero DOM.
once
   ...
passivo
   A Booleanche, se vero, indica che la funzione specificata da listenernon chiamerà mai preventDefault(). Se un ascoltatore passivo chiama preventDefault(), l'agente utente non farà altro che generare un avviso della console. ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.