12

这让我发疯了。这是一个很难解释的问题,但我会试一试。

我的网站首页上有一个输入文本字段。我编写了一个 keydown 事件观察器,它检查 keyCode,如果它的 ENTER(或等效),它将检查输入值(电子邮件)。如果电子邮件在数据库中有效且唯一,它将提交表单。基本的东西,或者你会这么想。

如果我在字段中输入我的电子邮件地址并按回车,它在所有浏览器中都可以正常工作。但是,如果我键入前几个字母,然后使用箭头键从历史下拉框中选择电子邮件(希望您知道我的意思),然后按回车,结果会有所不同。表单字段的值被捕获为我键入的几个字母,因此验证失败。似乎当我按回车键从历史下拉列表中“选择”电子邮件时,浏览器会中断,就好像我在打字一样。

在 Chrome 和 Safari 中,它可以正常工作。这应该意味着,当您按 Enter 从历史下拉列表中“选择”电子邮件时,它所做的只是将该电子邮件地址放入文本框中。只有在第二次按下 ENTER 键时,它才会触发事件观察器,并验证电子邮件。

希望有人能解释为什么会发生这种情况......我的直觉是它是浏览器的问题,并且将是我无法解决的问题。

谢谢李

编辑:为了澄清我的问题,让我补充一点,我使用“keydown”事件来捕捉按下回车键的时刻。我已经尝试过“keyup”事件,这解决了我上面的问题,但是我似乎无法自行停止提交表单。“keyup”事件在默认行为之后触发,因此它不是正确的选择。

进一步编辑:

再次感谢您,顺便说一句,您的英语非常好(回应您对英语不好的评论)。

我已经改变了我的事件处理程序:

$("emailInputBox").observe("keydown", function(event) {
    return submitViaEnter(event, submitSignupFormOne);
});

对此:

$("emailInputBox").observe("keydown", function(event) {
    setTimeout(submitViaEnter.curry(event, submitSignupFormOne),0);
});

submitViaEnter

function submitViaEnter(event, callback) {
var code = event.keyCode;
if (code == Event.KEY_RETURN) {
    event.stop();
    return callback(event);
}
return true;
}

似乎可以工作,但现在的问题是允许浏览器在运行该submitViaEnter功能之前执行默认操作,这意味着当我按 ENTER 时正在提交表单。

4

2 回答 2

7

回答原始问题

是的,这是一个 Gecko 错误(虽然不是 Mac 特定的)。

此评论的最后一部分包含解决方法的描述:使用超时。

[编辑] 因为您要求澄清错误

当您按 Enter 并且自动完成处于活动状态时,Firefox(错误地)首先触发页面的键处理程序,然后关闭自动完成弹出窗口并更新文本区域值的浏览器内部键处理程序,而它可以说应该只是在自动完成弹出窗口,只让页面知道文本框值已更改。

这意味着当你的键处理程序被调用时,自动完成的处理程序还没有运行——自动完成弹出窗口仍然打开,文本框的值就像自动完成发生之前一样。

当您setTimeout向您的密钥处理程序添加调用时,您是在对浏览器说“嘿,在您完成 P1 待办事项列表中已有的事情后立即运行此函数”。所以自动完成的处理程序运行,因为它已经在待办事项列表中,然后你放在超时的代码运行 - 当自动完成弹出窗口已经关闭并且文本框的值更新时。

[编辑] 回答“进一步编辑”中的问题

对。如果您希望它工作,您需要取消事件处理程序中的默认操作,而不是超时:

function onKeyPress(ev) {
  if (... enter pressed ...) {
    setTimeout(function() {
      ... check the new textbox value after letting autocomplete work ...
    }, 0);
    // but cancel the default behavior (submitting the form) directly in the event listener
    ev.preventDefault();
    return false;
  }
}

如果您仍然想在 Enter 上提交表单,这将是一个更有趣的练习,但您似乎没有这样做。

于 2010-02-20T23:48:11.283 回答
2

好的排序它。非常感谢你的帮助。这是我之前缺少的咖喱功能。我试图在 setTimeout 函数范围内处理事件。

这在下面有效。submitViaEnter 从 eventobserver 调用并响应 keyDown 事件:

function submitViaEnter(event, callback) {
var code = event.keyCode;
if (code == Event.KEY_RETURN) {
    event.stop();
    setTimeout(callback.curry(event),0);        
    // return callback(event);
    // return false;    
}
return true;
}

停止 eventObserver 中的默认操作意味着不能输入任何字符。所以我陷入了 if ENTER key 子句。

于 2010-02-21T17:23:10.653 回答