Отключить прокрутку клавиш со стрелками в браузере пользователей

87

Я делаю игру, используя холст и javascript.

Когда страница длиннее экрана (комментарии и т. Д.), Нажатие стрелки вниз прокручивает страницу вниз и делает игру невозможной.

Что я могу сделать, чтобы окно не прокручивалось, когда игрок просто хочет спуститься вниз?

Я полагаю, что с играми Java и т.п. это не проблема, пока пользователь нажимает на игру.

Я попробовал решение из: Как отключить прокрутку страницы в FF с помощью клавиш со стрелками , но я не мог заставить его работать.

Kaninepete
источник

Ответы:

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.
Ludder 09
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. Его значение - это обрабатываемый в данный момент объект Event.

Дальнейшие чтения:

Йом С.
источник
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 Необязательный
   Объект параметров определяет характеристики прослушивателя событий. Доступные варианты:

capture
   A, Booleanуказывающий, что события этого типа будут отправлены зарегистрированным пользователям listenerперед отправкой любому из EventTargetних в дереве DOM.
Once
   ...
passive
   A, Booleanкоторый, если он истинен, указывает, что функция, указанная в listener, никогда не будет вызывать preventDefault(). Если пассивный прослушиватель действительно вызывает preventDefault(), пользовательский агент не будет делать ничего, кроме создания консольного предупреждения. ...

Almaceleste
источник