使用iframe阻止按键的默认动作

4
这是一个我无法解决的进退两难局面。以我们托管的HTML5游戏为例:http://www.scirra.com/arcade/action/93/8-bits-runner(警告有声音!)该页面托管在scirra.com上,但由于安全原因,游戏在static1.scirra.net的iframe中展示。现在,当您在玩游戏时按左、右、上或下方向键时,整个窗口会上下或左右滚动。当游戏未获得焦点时,preventDefault功能似乎正常工作。当然,在玩游戏时我们希望阻止这种默认操作!因此,我们使用以下代码:
    var ar = new Array(32, 33, 34, 35, 36, 37, 38, 39, 40, 44);
    $(document).keydown(function (e) {            
        var key = e.which;
        if ($.inArray(key, ar) > -1) {
                e.preventDefault();
                return false;
        }
        return true;
    });

我们需要在父页面和 iframe 页面上添加此代码。当 iframe 获得焦点时,左右滚动似乎被阻止了,但是上下滚动没有受到影响。有人能帮助我们找出如何停止页面滚动的方法,并仍然允许人们在游戏下方的评论框中输入评论吗?如果您阻止空格键,则会阻止用户在文本中添加空格!
5个回答

5
我可能无法完全理解问题,但看起来你想要以下内容:
  1. 只有在游戏窗口获得焦点的情况下,才能使用上下空格等按键。
  2. 在评论框获得焦点时,可以使用上下空格等按键。
  3. 在主窗口获得焦点时,可以使用上下空格等按键。
2号和3号会自动发生,如果您什么都不做的话。因此,基本上您想要的是1号。我不明白为什么您需要对主窗口编写任何代码。
在我的测试中,这适用于Chrome、Opera、FF、IE9、IE8和IE7。
主窗口
演示:http://jsfiddle.net/ThinkingStiff/Dp5vK/ HTML:
<iframe id="game" src="http://jsfiddle.net/ThinkingStiff/dtmxy/show/"></iframe>
<textarea id="comment-box"></textarea>

CSS:

#game {
    border: 1px solid red;
    display: block;
    height: 100px;
    width: 200px;
}

#comment-box {
    height: 100px;
    width: 200px;
}

body {
    height: 1000px;
    width: 1000px;
}

游戏窗口(iframe)

演示:http://jsfiddle.net/ThinkingStiff/dtmxy/

脚本:

$( document ).bind( 'keydown', function ( event ) {

    var keys = [32, 33, 34, 35, 36, 37, 38, 39, 40, 44];

    if( keys.indexOf( event.which ) > -1 ) {

        event.preventDefault();
        event.stopPropagation();

    };

} );

感谢提供演示,清楚地展示了它的工作原理。当我实施时,我发现了我犯的简单错误,并使其正常工作! - Tom Gullen

1
关于空格键的问题,您需要在keydown函数中检查用户是否刚刚聚焦于游戏下方的评论框。如果被聚焦了,则临时允许空格键。

1

看看将其更改为仅在游戏 DIV 上捕获是否有所帮助。

$('div.arcade-content').on('keydown', 'div.game-wrapper', function (e) {
    ...
});

1
给你的游戏画布添加一个 tabindex。值为 0 将把画布元素放入常规基于源的选项卡顺序中。然后它将能够接收焦点并充当键事件的目标,这意味着你只能防止来自你的画布的键事件的默认操作和事件传播。
$canvas = $("#c2canvas");
$canvas.tabIndex = 0;

var ar = [32, 33, 34, 35, 36, 37, 38, 39, 40, 44];
$canvas.keydown(function (e) {            
    var key = e.which;
    if ($.inArray(key, ar) > -1) {
        e.preventDefault();
        e.stopPropagation();
    }
});

嗨,感谢您的回答。按照建议实施后,iframe HTML页面已经有了那段代码,但仍然可以上下滚动页面。FF没问题,但Chrome和IE会上下滚动。如果事件是从该框架发起的,似乎无法捕获上下键事件。 - Tom Gullen

0

我在将我的游戏嵌入到WordPress内容页面的iframe中时遇到了同样的问题。不幸的是,上面的解决方案无法使用 preventDefault()stopPropagation() 来防止按键事件。因此,我通过切换CSS类来设置body的overflow: hidden,并通过按键或鼠标滚轮页面滚动来设置/取消iframe的焦点,最终解决了这个问题。

document.addEventListener('keydown', function(e) {
  document.body.classList.add('no-scroll');
  document.getElementsByTagName('iframe')[0].focus();
});
document.addEventListener('wheel', function(e) {
    document.body.classList.remove('no-scroll');
    if (document.activeElement) {
        document.activeElement.blur();
    }
});
.no-scroll {
    overflow: hidden;
}

这是工作示例:石头迷阵


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接