在用户浏览器中禁用箭头键滚动


87

我正在使用画布和JavaScript开发游戏。

当页面比屏幕长(注释等)时,按向下箭头将页面向下滚动,使游戏无法进行。

当播放器只想向下移动时,如何防止窗口滚动?

我猜对于Java游戏而言,只要用户点击游戏,这都不是问题。

我尝试了以下解决方案:如何使用箭头键禁用FF中的页面滚动,但无法正常工作。

Answers:


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了keyup侦听器。修复了此问题,并在Firefox和Chrome中对其进行了测试。请注意,对的所有更改keys都是可选的,但是由于您正在构建游戏……
Zeta 2012年

在某些较旧的(移动)浏览器中,箭头键甚至都不会触发键事件... :-(
Michael

1
如果执行此操作,并且网页上有任何字段输入,则将无法使用空格键或箭头键导航文本。我发现了很大的缺点。
单一实体

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事件处理程序时才可用。它的值是当前正在处理的Event对象。

进一步阅读:


0

我尝试过用不同的方法来阻止按下箭头键时的滚动,包括jQuery和本机Javascript-它们在Firefox中都可以正常工作,但在最新版本的Chrome中不起作用。
即使是明确的{passive: false}属性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然后再分派给EventTargetDOM树中其下的任何事件。
一旦
   ...
被动
   A Boolean,如果为true,则表示所指定的函数listener将永远不会调用preventDefault()。如果被动侦听器确实进行了调用preventDefault(),则用户代理将不执行任何操作,只生成控制台警告。...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.