4

我正在使用 Javascript / JQuery 创建一个基于 Web 的实验,它要求用户通过按下某些键而不是其他键来给出响应。如果他们按错了键,他们应该会收到一个警报弹出窗口,告诉他们他们按错了键。在显示警报时,实验应该停止等待下一次按键,但一旦警报解除,就会返回等待。

我遇到的问题是,如果通过按 ENTER 键解除警报,它似乎是由键事件处理程序注册的,从而触发另一个警报(因为 ENTER 不是允许的键之一),即使我以为我的编写方式是在解除警报之前不应调用键事件处理程序。我的问题是,如何确保随后调用的事件处理程序不会收到用于解除警报的 ENTER 按键?

这是一些代码:

function waitForKeypress( permittedKeys, callbackFn ) {
    returnFn = function(e) {
        $(document).unbind('keyup',returnFn);
        if ( permittedKeys.indexOf( e.which )!=-1 ) {
            callbackFn( { "success": true, "value": e.which } );
        } else {
            callbackFn( { "success": false } );
        }
    }
    $(document).keyup( returnFn );
}

var callback = function(data) {
    if ( data.success ) {
        goDoOtherStuff();
    } else {
        alert( "error message" );
        waitForKeyPress( permittedKeys, callback );
    }
}

waitForKeyPress( permittedKeys, callback );

我应该解释一下,我认为用于解除警报的 ENTER 按键不会被 waitForKeyPress 中的事件处理程序接收的原因是因为(我认为)只要显示警报,Javascript 就应该停止执行,以便 waitForKeyPress 调用回调函数内部不应该关闭,直到警报被解除,也就是说,在 ENTER 键被释放之后。

(我的实际 waitForKeyPress 比上面更复杂 - 它等待按键对,只允许某些对,这就是为什么我首先需要将它作为一个单独的函数的原因。我不认为这些东西不过,我删除的内容与我的问题有关。)

编辑:有些人认为这可能与事件处理程序没有正确解除绑定有关。我确定这不是问题。这是一个更简洁的示例,其中事件处理程序甚至在警报之后才被绑定,但出现了同样的问题:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
alert( "Hello world" );
$(document).keyup( function() { alert( "Goodbye cruel world." ) } );
</script>
</html>

按下 ENTER 键关闭 Hello World 将立即调用 Goodbye 残酷世界。

4

1 回答 1

3

在显示警报之前取消绑定 keyUp

编辑#1

我在 Safari 6 OS X 10.7 上尝试了您在编辑中的示例代码。

你是对的。

发生这种情况是因为当发生 Return keydown时,按下了具有等效键“Return”的标准按钮,例如警报对话框的 tke“Ok”(我的意思是按钮)。换句话说,当用户按下回车键并且不等待回车键被释放时,对话框将被关闭。

所以用户按下“Return”,对话框被关闭,keyup 被绑定,用户释放“Return”,事件被触发。

您可以通过不同的方式解决此问题。

更简单的(如果它符合您的需要)是绑定 keydown 而不是 keyup

alert( "Hello world" );
$(document).keydown( function() { alert( "Goodbye cruel world." ) } );

否则,您可以检查按下了什么键并忽略“返回”。

请记住,keydown 也可以通过按 CMD(例如,如果用户想使用 CMD-W 关闭窗口)、箭头键(如果内容大于视口,通常允许用户滚动窗口)等来触发。

因此,如果您使用 keyup 或切换到 keydown,则某种过滤将是合适的。

希望这可以帮助

于 2013-02-01T23:39:20.047 回答