사용자 브라우저에서 화살표 키 스크롤 비활성화


87

캔버스와 자바 스크립트를 사용하여 게임을 만들고 있습니다.

페이지가 화면 (코멘트 등)보다 길 때 아래쪽 화살표를 누르면 페이지가 아래로 스크롤되어 게임을 플레이 할 수 없게됩니다.

플레이어가 아래로 이동하려고 할 때 창이 스크롤되지 않도록하려면 어떻게해야합니까?

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

Note that this approach also enables you to remove the event handler later if you need to re-enable arrow key scrolling:

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

References


8
I really like this solution, but it doesn't seem to work in chrome =/
Kaninepete

1
@Kaninepete: There was a syntax error, I used lC.keys instead of keys in the keyup listener. Fixed this and tested it in Firefox and Chrome. Notice that all changes to keys are optional, but since you are building a game...
Zeta

in some older (mobile) browsers, it seems that the arrow keys don't even fire key events... :-(
Michael

1
If you do this, and you have any field inputs on your web page then it you won't be able to use the spacebar or the arrow keys to navigate the text. Big drawback I found.
Single Entity

9
Note that you really need to use keydown and not keyup.
Ludder

4

For maintainability, I would attach the "blocking" handler on the element itself (in your case, the canvas).

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

Why not simply do window.event.preventDefault()? MDN states:

window.event is a proprietary Microsoft Internet Explorer property which is only available while a DOM event handler is being called. Its value is the Event object currently being handled.

Further readings:


0

I've tried different ways of blocking scrolling when the arrow keys are pressed, both jQuery and native Javascript - they all work fine in Firefox, but don't work in recent versions of Chrome.
Even the explicit {passive: false} property for window.addEventListener, which is recommended as the only working solution, for example here.

In the end, after many tries, I found a way that works for me in both Firefox and 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
});

Quote for EventTarget.addEventListener() from MDN

options Optional
   An options object specifies characteristics about the event listener. The available options are:

capture
   A Boolean indicating that events of this type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree.
once
   ...
passive
   A Boolean that, if true, indicates that the function specified by listener will never call preventDefault(). If a passive listener does call preventDefault(), the user agent will do nothing other than generate a console warning. ...

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.