Вимкніть прокрутку клавіш зі стрілками в браузері користувачів


87

Я роблю гру за допомогою полотна та javascript.

Якщо сторінка довша за екран (коментарі тощо), натискання стрілки вниз прокручує сторінку вниз і робить гру неможливою.

Що я можу зробити, щоб вікно не прокручувалося, коли гравець просто хоче рухатися вниз?

Я думаю, що з іграми Java, і такими, це не проблема, поки користувач натискає гру.

Я спробував рішення з: Як вимкнути прокрутку сторінки в FF за допомогою клавіш зі стрілками , але я не зміг змусити його працювати.

Відповіді:


164

Резюме

Просто запобігайте дії браузера за замовчуванням :

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

Оригінальна відповідь

Я використав таку функцію у власній грі:

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

Магія відбувається в e.preventDefault();. Це заблокує дію події за замовчуванням, в цьому випадку переміщуючи точку зору браузера.

Якщо вам не потрібні поточні стану кнопки, ви можете просто відпустити keysта просто відкинути дію за замовчуванням на клавішах зі стрілками:

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

Зверніть увагу, що цей підхід також дозволяє вам видалити обробник подій пізніше, якщо вам потрібно знову ввімкнути прокрутку клавіш зі стрілками:

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

Список літератури


8
Мені дуже подобається це рішення, але воно, схоже, не працює в chrome = /
Kaninepete

1
@Kaninepete: Виникла синтаксична помилка, яку я використав lC.keysзамість keysу прослуховувачі клавіш. Виправлено та перевірено у Firefox та Chrome. Зверніть увагу, що всі зміни до keysнеобов’язкові, але оскільки ви будуєте гру ...
Зета,

у деяких старих (мобільних) браузерах здається, що клавіші зі стрілками навіть не запускають ключові події ... :-(
Майкл

1
Якщо ви зробите це, і на вашій веб-сторінці є будь-які введені поля, тоді ви не зможете використовувати пробіл або клавіші зі стрілками для навігації по тексту. Великий недолік я знайшов.
Single Entity,

9
Зверніть увагу, що вам дійсно потрібно користуватися, keydownа ні keyup.
Люддер

4

Для ремонтопридатності я б прикріпив обробник "блокування" до самого елемента (у вашому випадку полотна).

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

Чому б просто не зробити window.event.preventDefault()? MDN стверджує:

window.eventє власною властивістю Microsoft Internet Explorer, яка доступна лише під час виклику обробника подій DOM. Його значенням є об’єкт події, який обробляється в даний час.

Подальші читання:


0

Я пробував різні способи блокування прокрутки при натисканні клавіш зі стрілками, як jQuery, так і власний Javascript - усі вони чудово працюють у Firefox, але не працюють в останніх версіях Chrome.
Навіть явне {passive: false}властивість for window.addEventListener, яке рекомендується як єдине робоче рішення, наприклад тут .

Зрештою, після багатьох спроб, я знайшов спосіб, який працює для мене як у Firefox, так і в 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
});

Цитувати для EventTarget.addEventListener()від MDN

options Необов’язково
   Об’єкт options визначає характеристики прослуховувача подій. Доступні варіанти:

захват
   A, що Booleanвказує на те, що події цього типу будуть відправлені зареєстрованим listenerперед тим, як будуть відправлені будь-якому EventTargetпід ним у дереві DOM.
один раз
   ...
пасивний
   A, Booleanякий, якщо true, вказує на те, що функція, визначена параметром, listenerніколи не викличе preventDefault(). Якщо пасивний слухач все-таки викличе preventDefault(), користувальницький агент не зробить нічого іншого, як генерує попередження консолі. ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.