Nonaktifkan scrolling tombol panah di browser pengguna

87

Saya membuat game menggunakan kanvas, dan javascript.

Ketika halaman lebih panjang dari layar (komentar, dll.) Menekan panah bawah akan menggulung halaman ke bawah, dan membuat permainan tidak mungkin untuk dimainkan.

Apa yang dapat saya lakukan untuk mencegah jendela bergulir saat pemain hanya ingin bergerak ke bawah?

Saya kira dengan game Java, dan semacamnya, ini tidak menjadi masalah, selama pengguna mengklik game tersebut.

Saya mencoba solusi dari: Cara menonaktifkan pengguliran halaman di FF dengan tombol panah , tetapi saya tidak dapat membuatnya berfungsi.

Kaninepete
sumber

Jawaban:

165

Ringkasan

Cukup cegah tindakan browser default :

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

Jawaban asli

Saya menggunakan fungsi berikut di game saya sendiri:

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

Keajaiban terjadi di e.preventDefault();. Ini akan memblokir tindakan default dari acara tersebut, dalam hal ini memindahkan sudut pandang browser.

Jika Anda tidak memerlukan status tombol saat ini, Anda cukup melepas keysdan membuang tindakan default pada tombol panah:

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

Perhatikan bahwa pendekatan ini juga memungkinkan Anda untuk menghapus pengendali kejadian nanti jika Anda perlu mengaktifkan kembali pengguliran tombol panah:

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

Referensi

Zeta
sumber
8
Saya sangat suka solusi ini, tetapi tampaknya tidak berfungsi di chrome = /
Kaninepete
1
@Kaninepete: Ada kesalahan sintaks, yang saya gunakan, lC.keysbukan keysdi pendengar keyup. Memperbaiki ini dan mengujinya di Firefox dan Chrome. Perhatikan bahwa semua perubahan keysadalah opsional, tetapi karena Anda sedang membuat game ...
Zeta
di beberapa peramban (seluler) yang lebih lama, tampaknya tombol panah bahkan tidak mengaktifkan peristiwa penting ... :-(
Michael
1
Jika Anda melakukan ini, dan Anda memiliki masukan bidang pada halaman web Anda, maka Anda tidak akan dapat menggunakan bilah spasi atau tombol panah untuk menavigasi teks. Kelemahan besar yang saya temukan.
Entitas Tunggal
9
Perhatikan bahwa Anda benar-benar perlu menggunakan keydowndan tidak keyup.
Ludder
4

Untuk pemeliharaan, saya akan memasang penangan "pemblokiran" pada elemen itu sendiri (dalam kasus Anda, kanvas).

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

Mengapa tidak melakukannya window.event.preventDefault()? MDN menyatakan:

window.eventadalah properti milik Microsoft Internet Explorer yang hanya tersedia saat pengendali kejadian DOM dipanggil. Nilainya adalah objek Peristiwa yang saat ini ditangani.

Bacaan lebih lanjut:

Yom S.
sumber
1

Saya telah mencoba berbagai cara untuk memblokir pengguliran saat tombol panah ditekan, baik jQuery maupun Javascript asli - semuanya berfungsi dengan baik di Firefox, tetapi tidak berfungsi di versi terbaru Chrome.
Bahkan {passive: false}properti eksplisit untuk window.addEventListener, yang direkomendasikan sebagai satu-satunya solusi yang berfungsi, misalnya di sini .

Pada akhirnya, setelah banyak mencoba, saya menemukan cara yang berhasil untuk saya di Firefox dan 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
});

Kutipan untuk EventTarget.addEventListener()dari MDN

options Opsional
   Objek options menentukan karakteristik tentang event listener. Opsi yang tersedia adalah:

capture
   A Booleanmenunjukkan bahwa kejadian jenis ini akan dikirim ke terdaftar listenersebelum dikirim ke EventTargetbawahnya di pohon DOM.
Once
   ...
passive
   A Booleanyang, jika true, menunjukkan bahwa fungsi yang ditentukan oleh listenertidak akan pernah dipanggil preventDefault(). Jika pendengar pasif menelepon preventDefault(), agen pengguna tidak akan melakukan apa pun selain membuat peringatan konsol. ...

almaceleste.dll
sumber