仅当用户与<canvas> </canvas>交互时才禁用箭头键滚动

时间:2011-09-29 20:40:31

标签: javascript scroll addeventlistener html5-canvas event-listener

我在JS中添加了一个事件监听器来监听keyup / keydown事件,我试图在HTML画布上移动一个精灵。我有大部分工作,但当用户按下箭头键时页面正在滚动。

我回归虚假,这似乎不起作用。另外,我的理解是以这种方式返回false会禁用整个页面的箭头按钮滚动。我想只在用户与画布本身交互时禁用它。

这是我的事件监听器:

addEventListener('keydown', function(e){
    move = false;
    x = false;
    y = false;
    var keycode;
    if (window.event) keycode = window.event.keyCode;
    else if (e) keycode = e.which;
    switch(keycode){
        case 37:
            move = true;
            x = 'negative';
        break;
        case 38:
            move = true;
            y = 'negative'
        break;
        case 39:
            move = true;
            x = 'positive'
        break;
        case 40:
            move = true;
            y = 'positive'
        break;
    }
    if(move){
        animation.move(x,y);
    }
    return false;
})

修改

下面的答案很清楚如何确保画布是聚焦的,但我仍然感到疑惑为什么在我的EventListener函数中返回false,返回false并不禁用滚动。

3 个答案:

答案 0 :(得分:11)

只要你以某种方式给你的画布焦点(即canvas.tabIndex = 1;),你就可以在你的e.preventDefault()之前添加return false,它会起作用。

示例:

http://jsfiddle.net/faAkN/

答案 1 :(得分:1)

我遇到了类似的问题,并提出了修复方法。

以下是我提出的建议:

function $(){
  return document.querySelector.apply(document,arguments);
}
var canvas = $('canvas'),
    keysDown = []; // You can also define this as an object, {}
canvas.tabIndex = 0;
canvas.onclick = function(e){
  document.body.scrollTop = canvas.offsetTop; // scrolls to canvas element
  canvas.focus(); // re-focuses canvas in case the scroll unfocused it
}
canvas.onkeydown = canvas.onkeyup = function(e){
  keysDown[e.keyCode] = e.type == 'keydown';
  e.preventDefault();
  return false;
}
function isDown(key){
  return keysDown[key];
}
function resetMap(){
  keysDown = [];
  return false;
}

要检查密钥是否已关闭,请在间隔循环或keydown函数中使用isDown(keycode)

对于常规密钥监听器:

canvas.onkeydown = canvas.onkeyup = function(e){
  // [...]
  if(isDown(17) && isDown(32)){ // Ctrl + Space
    alert('Ctrl and Space were pressed');
    resetMap();
  }
  e.preventDefault();
  return false;
}

对于类似于ActionScript 2.0的Key.isDown

的快速键侦听器
function KeyLoop(){
  if(isDown(17) && isDown(32)){ // Ctrl + Space
    console.log('Lots of text');
    resetMap();
  }
  setTimeout(keyLoop,1000/24); // @ 24 fps
}
keyLoop();

我在这里做了一个不同的动作有两个原因:1)将alert()与重复间隔混合从来不是一个好主意,2)证明缺少延迟,这就是使它类似于AS2的原因Key.isDown()功能。要查看记录的文本,请打开firebug或常规JavaScript控制台。在Chrome中, Ctrl Shift J 。在Firefox中, Ctrl Shift K


这应该通过在单击画布时关注元素来修复滚动问题。另外一个好处是,您可以一次检查多个键,因为您使用keysDown[]作为原始事件的抽象,使8方向游戏变得容易。

答案 2 :(得分:0)

你尝试过这样的事吗?

<script type="text/javascript">
    canvas_active = false;
</script>

<canvas onfocus="javascript: canvas_active = true;" onblur="javascript: canvas_active = false;" />

然后在当前方法中检查canvas_active是否为true,如果是,则返回false,否则返回true。只有当画布在移动时才聚焦,这才有效。