Javascript:如何防止用于解除警报的按键触发按键事件处理程序

Javascript:如何防止用于解除警报的按键触发按键事件处理程序,javascript,jquery,event-handling,alert,keyevent,Javascript,Jquery,Event Handling,Alert,Keyevent,我正在使用Javascript/JQuery创建一个基于web的实验,该实验要求用户通过按某些键给出响应,而不是其他键。如果他们按错了键,他们应该会得到一个提示弹出窗口,告诉他们按错了键。当警报显示时,实验应停止等待下一次按键,但在警报解除后返回等待 我遇到的问题是,如果通过按ENTER键解除警报,它似乎由键事件处理程序注册,从而触发另一个警报(因为ENTER键不是允许的键之一),尽管我认为我是这样写的,在警报解除之前不应该调用键事件处理程序。我的问题是,如何确保用于解除警报的ENTER键不会被

我正在使用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 );
我应该解释一下,我认为waitForKeyPress中的事件处理程序不会接收到用于解除警报的ENTER键的原因是(我认为)只要显示警报,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>

警报(“你好世界”);
$(document).keyup(函数(){alert(“再见残酷世界”)});

按ENTER键取消Hello World将立即调用再见残酷世界。

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

编辑#1

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

你说得对

发生这种情况的原因是,当返回keydown发生时,标准按钮(如警报对话框的tke“Ok”)被按下(我指的是按钮),这些按钮具有与“Return”等价的键。换言之,当用户返回时,对话框将被取消,并且不会等待返回被释放

因此,用户按下“返回”,对话框被取消,键被绑定,用户释放“返回”,事件被触发

你可以用不同的方法来处理这种行为

更简单的方法(如果它适合您的需要)是绑定keydown而不是keydup

alert( "Hello world" );
$(document).keydown( function() { alert( "Goodbye cruel world." ) } );
否则,您可以检查按下的键并忽略“返回”

请记住,按下CMD(例如,如果用户想用CMD-W关闭窗口)、箭头键(如果内容比视口大,通常允许用户滚动窗口)也会触发keydown

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


希望这有助于

更改警报以确认并读取返回值。调用e.preventDefault()?@rlemon-Done-confirm在我按ENTER键时返回“true”-因此。。。现在怎么办?@SteveH完成,但这似乎没有改变任何东西-为什么会改变?在显示确认时解除事件绑定。在确认结束时重新绑定。我当前的代码不是已经这样做了吗?(在returnFn的开头,我解开了keyup。)我添加了一个更简单的例子来说明这个问题与警报之前发生的任何事情都没有关系。谢谢!这些解决方案有效。有没有办法更改警报的默认行为,以便在按下ENTER键时以keyup而不是keydown结束?我很确定这是不可能的。在现代网站上,也许“警报”不是与用户交互的好方法。javascript实现的模式对话框。最终利用jquery。看看这个,有一些样品