我在mac上的Firefox中遇到keydown事件和自动完成问题

时间:2010-02-20 22:11:43

标签: javascript macos firefox prototypejs keycode

这让我疯了。这是一个难以解释但我会去的。

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

如果我在字段中输入我的电子邮件地址并按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时正在提交表单。

2 个答案:

答案 0 :(得分:7)

回答原始问题

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

The last part of this comment包含解决方法的说明:使用超时。

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

按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上提交表单,那将是一个更有趣的练习,但您似乎并不这样做。

答案 1 :(得分:2)

好的排序吧。非常感谢你的帮助。这是我以前失踪的咖喱功能。我正在尝试处理setTimeout函数范围内的事件。

这适用于以下内容。从eventobserver调用submitViaEnter并响应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键子句。