Why does forms with single input field submit upon pressing enter key in input

Why is it that a <form> with a single <input> field will reload the form when the user enters a value and presses the Enter, and it does not if there are 2 or more fields in the <form>?.

I wrote a simple page to test this oddity.

If you enter a value in the second form and press Enter, you'll see it reloads the page passing the entered value as if you called GET. why? and how do I avoid it?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>testFormEnter</title>
</head>
<body>
<form>
<input type="text" name="partid2" id="partid2" />
<input type="text" name="partdesc" id="partdesc"  />
</form>
<p>2 field form works fine</p>
<form>
<input type="text" name="partid" id="partid"  />
</form>
<p>One field form reloads page when you press the Enter key why</p>
</body>
</html>
38537 次浏览

这是一个鲜为人知的“怪癖”,已经出来了一段时间。我知道有些人已经用各种方式解决了这个问题。

在我看来,最简单的绕过方法是只有一个不显示给用户的第二个输入。虽然后端的用户界面并不那么友好,但它确实可以解决这个问题。

我应该指出的是,我听到的最常见的地方,这个问题是与 IE 具体而不是与火狐或其他。虽然这似乎也影响到了他们。

它不是像这样重新加载页面,而是提交表单。

但是,在这个示例中,由于在它提交给自己的表单上没有 action 属性,因此给人一种重新加载页面的感觉。

还有,我不能复制你描述的行为。如果我在表单中的任何文本输入中,并按 Enter 它提交表单,无论输入位于表单的哪个位置或有多少个输入。

您可能希望在不同的浏览器中进行更多的尝试。

这是一个 IE6/7/8已知的漏洞。看起来你不会得到一个修复。

您可以为此做的最佳解决方案是添加另一个隐藏字段(如果您的工程良心允许的话)。IE 发现表单中有两个输入类型字段时,将不再自动提交表单。

更新

如果你想知道为什么会出现这种情况,这个宝石直接来自于 HTML 2.0规范(第8.2节):

如果窗体中只有一个单行文本输入字段,则 User agent 应该接受该字段中的 Enter 作为提交请求 表格。

根据(a)有多少个字段和(b)有多少个提交按钮,按回车键的工作方式不同。它可能什么也不做,它可能提交没有“成功”提交按钮的表单,或者它可能假装第一个提交按钮被点击(甚至为它生成一个 onclick!)然后按那个按钮的值提交。

例如,如果在两个字段的表单中添加一个 input type="submit",您会注意到它也提交了。

这是一个古老的浏览器怪癖,至少可以追溯到早期的网景(也许更早) ,现在不太可能改变。

< 表格 >

没有“动作”就无效。如果您不打算在任何地方提交,并且不需要单选按钮名称分组,那么可以完全忽略表单元素。

感谢所有接电话的人。单个字段的表单与多个字段的表单的作用不同,这让人大开眼界。

处理这种自动提交的另一种方法是编写一个返回 false 的提交函数。

在我的例子中,我有一个带有 onclick 事件的按钮,所以我将带有添加的 return关键字的函数调用移动到了 oncommit 事件。如果调用的函数返回 false,则不会发生提交。

<form onsubmit="return ajaxMagic()">
<input type="text" name="partid" id="partid"  />
<input type="submit" value="Find Part" />
</form


function ajaxMagic() {
...
return (false);
}

下面是我用来解决这个问题的代码:

<form>
<input type="text" name="partid" id="partid"  />
<input type="text" name="StackOverflow1370021" value="Fix IE bug" style="{display:none}" />
</form>

我为我测试的所有浏览器(IE,FF,Chrome,Safari,Opera)找到的解决方案是,表单中的第一个输入 type=submit元素必须是可见的,并且必须是表单中的第一个元素。我能够使用 CSS 布局移动提交按钮到页面的底部,它不影响结果!

<form id="form" action="/">
<input type="submit" value="ensures-the-enter-key-submits-the-form"
style="width:1px;height:1px;position:fixed;bottom:1px;"/>
<div id="header" class="header"></div>
<div id="feedbackMessages" class="feedbackPanel"></div>
...... lots of other input tags, etc...
</form>

正如 vineet 已经说过的,这植根于 html 2.0规范:

以下是如何防止这种情况发生,同时又不会搞砸你的网址:

<form>
<input type="text" name="partid" id="partid"  />
<input type="text" style="display: none;" />
</form>

这个问题在 IE 和 Chrome 中都会出现。 Firefox 上不会出现这种情况。 一个简单的解决方案是向 form 标记添加以下属性: “返回 false”

当然,前提是您使用 XMLHttpRequest 对象提交表单。

是的,只有一个 inputText 字段的表单在 HTML4中的工作方式是不同的。
OnSubmit 返回 false 对我来说不起作用,但是下面的修复 bug 工作的很好

<!--Fix  IE6/7/8 and  HTML 4 bug -->
<input style="display:none;" type="text" name="StackOverflow1370021" value="Fix IE bug" />

我通过下面的代码处理这个问题,但是我不确定这是否是一个好的方法。 通过查找给定表单中的输入字段,如果其1阻止默认操作,则执行。

 if($j("form#your-form input[type='text']").length == 1) {
$j(this).bind("keypress", function(event) {
if(event.which == 13) {
event.preventDefault();
}
});
}

我认为这是一个功能,虽然我也禁用了它。不费吹灰之力就能让它失效。只要捕获输入键,忽略它,就可以了。

不,默认行为是在输入时,表单中的最后一个输入被提交。 如果你根本不想提交,你可以添加:

<form onsubmit="return false;">

或者你的输入

<input ... onkeypress="return event.keyCode != 13;">

当然,还有更漂亮的解决方案,但是这些方案在没有任何库或框架的情况下更加简单。