按回车键时表单无法提交

49
我有以下HTML/JS/jQuery代码。这段代码代表一个登录表单,以模态方式呈现给用户,让他们登录。问题是,当我按回车键时,表单似乎没有执行“onsubmit”事件。当我点击表单底部的按钮(几乎与onsubmit事件相同)时,它完美地工作。我想知道是否有人能告诉我为什么这个表单没有提交..?任何帮助都将不胜感激。
jQuery代码显示登录模态窗口:
showDivAndFocus('loginModal','loginaccount'); 

function showDivAndFocus(v,t){

    if (api)
        if (api.isOpened)
            api.close();

    api = $('#'+v).overlay({
        mask: {color: '#000000'}, 
        top:'0px',
        api: true,
        autoScrollToActive: false,
        autoScrollOffset: 0 
    }).load();

    document.getElementById(t).focus();
}

HTML代码

<div class="modal" id="loginModal">
    <h2>User Login</h2>
    <br />

    <form action="javascript:void(0);" onsubmit="return(doLogin());"  name="loginForm" id="loginForm">
        <table width="95%" cellpadding="4" cellspacing="4">
        <tr>
        <td class="regw" align="left"><b>Account Number:</b></td>
        <td class="regw" align="left"><input type="text" maxlength="10" size="10" name="loginaccount" id="loginaccount" /></td>
        </tr>

        <tr>
        <td class="regw" align="left"><b>Username:</b></td>
        <td class="regw" align="left"><input type="text" maxlength="20" size="20" name="loginusername" id="loginusername" /></td>
        </tr>

        <tr>
        <td class="regw" align="left"><b>Password:</b></td>
        <td class="regw" align="left"><input type="password" maxlength="20" size="20" name="loginpassword" id="loginpassword" /></td>
        </tr>  

        <tr>
        <td class="regw" align="left"><b>Remember Me:</b></td>
        <td class="regw" align="left"><input type="checkbox" name="loginremember" id="loginremember" /></td>
        </tr>  

        <tr><td colspan="2">
            <div>  
                <center>
                    <table><tr><td width="50" valign="middle">
                        <div id="loginLoading" style="height:24px;width:24px;"></div>   
                    </td><td>
                        <button onclick="doLogin();" type="button" class="ok">Submit</button>
                    </td><td>
                        <button onclick="api.close();" type="button" class="cancel">Cancel</button>
                    </td><td width="50">&nbsp;</td></tr></table>
                </center>
            </div>
        </td></tr> 
        </table>
    </form>
</div>

AJAX调用

function doLogin(){
    var ajax = getXmlObject();
    var f = getFormVariables();
    var url= '/login.php?f=' + encodeURIComponent(f);
    if (ajax.readyState == 4 || ajax.readyState == 0) {
        ajax.open("POST", url, true);
        ajax.onreadystatechange = function () {
            if (ajax.readyState == 4) {
                var a = ajax.responseText;
                if (a=="OK"){...} else {...}
            }
        };
        ajax.send(null);
      }
      return false;
 }
9个回答

69
我曾经也遇到了同样的问题。我的一个表单可以在文本字段中按“Enter”键提交,而另一个类似的表单却始终无法提交。
这两个字段都没有提交按钮,并且都没有使用JavaScript提交。我发现,当表单中只有一个文本字段时,在文本字段中按“Enter”键将自动提交;但是,如果有多个(常规(即单行)文本输入)字段,则除非还有某种“提交”按钮,否则什么也不做。
显然,这是HTML 2.0规范的一部分:

当表单中只有一个单行文本输入字段时,用户代理应接受该字段中的Enter作为请求提交表单。

这里有一个旧的、但显然仍然有效且有趣的进一步讨论。
这显然是一种方便提交简单查询的方式,但在填写复杂表单时可以减少过早提交的风险。许多浏览器实现者(例如Netscape,Opera,不同版本的Lynx等)遵循了这个建议,尽管似乎有略微不同的解释。 我制作了一个JSFiddle演示。据我所知(懒得只用Chrome测试),如果只有一个文本字段或者有一个提交按钮,即使它是隐藏的,表单也会在“Enter”上提交。
<h2>Form with one text field only, no submit button</h2>
<p>Seems to submit automatically when pressing 'enter' in the first text field</p>
<form action="" method="post">
  <div>
    <label for="pt-search-input">Search</label>
    <div>
      <input name="term" type="text" placeholder="Example: budapest amsterdam" /> <a href="#pt-search-bar">cancel</a></div>
  </div>
</form>

<h2>Form with two text fields, no submit button</h2>
<p>Won't submit when pressing 'enter' in the forms ...</p>
<form action="" method="post">
  <div>
    <label for="pt-search-input">Search</label>
    <div>
      <input name="term" type="text" placeholder="Example: budapest amsterdam" />
      <input name="term2" type="text" placeholder="Example: budapest amsterdam" /> <a href="#pt-search-bar">cancel</a></div>
  </div>
</form>



<h2>Form with two text fields and a submit button ...</h2>
<p>Now it submits with 'enter' key</p>
<form action="" method="post">
  <div>
    <label for="pt-search-input">Search</label>
    <div>
      <input name="term" type="text" placeholder="Example: budapest amsterdam" />
      <input name="term2" type="text" placeholder="Example: budapest amsterdam" /> <a href="#pt-search-bar">cancel</a>
      <input type="submit" />
    </div>
  </div>
</form>

<h2>Form with two text fields and a HIDDEN submit button ...</h2>
<p>Seems to work, even with submit hidden ...</p>
<form action="" method="post">
  <div>
    <label for="pt-search-input">Search</label>
    <div>
      <input name="term" type="text" placeholder="Example: budapest amsterdam" />
      <input name="term2" type="text" placeholder="Example: budapest amsterdam" /> <a href="#pt-search-bar">cancel</a>
      <input type="submit" />
    </div>
  </div>
</form>


<h2>Form with no action or method attribute, HIDDEN submit button ...</h2>
<p>Even this seems to work.</p>
<form>
  <div>
    <label for="search-input">Search</label>
    <div>
      <input name="term" type="text" placeholder="Example: budapest amsterdam" />
      <input name="term2" type="text" placeholder="Example: budapest amsterdam" /> <a href="#pt-search-bar">cancel</a>
      <input type="submit" />
    </div>
  </div>
</form>

<h2>Form with multiple fields, but only one text input, no submit button.</h2>
<p>This seems to work as well.</p>
<form action="" method="post">

  <p><input type="text" ></p>

  <textarea name="" id="" cols="30" rows="10"></textarea>

  <p>
    <select name="" id="">
      <option value="">Value</option>
    </select>
   </p>
</form>

2
我认为您错过了“一个单行文本输入框”的精度。如果其他字段不是“单行文本输入框”,表单甚至会被提交多个字段。您可以快速检查此JSFiddle。顺便说一句,您的答案是正确的,帮助我解决了我的问题。 - user3292788
@user3292788 哦,好的。是的,我没有注意到这一点,因为我的都是普通文本输入字段。没有想到要尝试其他类型的字段。: ) 谢谢您提供的额外信息。我更新了答案以反映这一点。 - Aaron Wallentine
我不认为这还是真的,至少对于HTML5来说不是。 - Dan

46

你有两种选择:

  1. 为回车按钮创建事件处理程序并将其添加到绑定中。
  2. 在表单中使用<input type=submit>,这是您想要的自动回车键行为。

1
我不相信这是真的。当按下回车键时,表单应该以任何方式提交。我有另一个几乎做同样事情的表单。它没有以“模态”显示,这是我唯一能看到的真正区别。但是可以确定的是,两个表单都没有提交按钮或onkeyX事件。 - Dutchie432
4
我会选择 <input type=submit>,因为它在语义上更正确。 - Timo Willemsen
2
@Dutchie432 - 据我所知(如果我错了,我很乐意接受纠正),您在其他表单上得到的行为可能是错误的,或者在按下回车键之前焦点转移到了其中一个提交按钮。HTML表单只应在使用<input type=submit>时通过Enter键提交。但是,如果您实际上将焦点放在按钮上,则可能会使用回车键“单击”它。 - g.d.d.c
28
请注意:如果一个表单没有提交按钮(<input type="submit"/><button type="submit"></button>),那么当它只有一个文本输入框时,按下回车键将自动提交表单。(详情请参见http://www.alanflavell.org.uk/www/formquestion.html)。带有提交按钮的表单应该会在按下回车键时提交,不管文本输入框的数量是多少(尽管我的一个表单现在并没有这样做,我不知道原因是什么)。另外,如果你的`<button>元素没有type`属性,在老版本的IE中它将充当一个提交按钮。 - Paul d'Aoust
2
针对@Pauld'Aoust的评论进行澄清 - [Enter] 只有在只有一个文本输入时才有效,而不是一个或多个。 - xyhhx
显示剩余6条评论

6
它也可以来自于JavaScript绑定在表单中的<button>上。例如,如果您有以下代码:
<button id='button'>Reset</button>
<span id="textToReset">some info</span>

<script type="text/javascript">
$('#button').bind('click', function(){  
    $('#textToReset').text('');     
    return false;
})
</script>

您的“Enter”按钮可能会被return false卡住,使得在按下“Enter”键时表单无法提交。正确的方法是指定<button>作为按钮的身份。代码如下:

<button id='button' type="button">Reset</button>

请删除您添加的 return false 代码,这样可以避免提交表单时阻止按钮。为了更好地学习,<button> 标签默认类型是 submit。如果您想将其作为表单的控件使用,必须指定 type="button"type="reset"请参考 w3.org

5
如果有人和我犯同样的错误并且在这里寻找答案:

如果您的表单中有两个(或更多)提交按钮1,按Enter键只会触发第一个提交按钮而不是第二个。


1@paul-daoust在@g-d-d-c的答案上指出: <input type=submit><button type=submit> 都可以作为提交按钮使用.


2
如果您的输入提交按钮正确,但在该按钮上使用(click)事件,则无法在按下回车键时触发它。显然,它会提交表单,但不会触发按钮的点击事件。将功能添加到表单本身及其提交事件将使其正常工作。

请详细阐述您的回答,并且要考虑到您的答案应该与已发布的答案不同。发布一些示例代码并解释您的代码与其他代码的区别。 - cloned
我也希望能够详细说明。你(或许)在谈论发生在我的身上的事情(尽管我的表格不是在点击而是提交时绑定:$('#myForm.on('submit',function(e){e.preventDefault();$.ajax({...});});). 点击<button type="submit">执行 AJAX (更新其他一些表单条目, 执行 SQL,...), 但是按 Enter 键会刷新页面, 这样就失去了 POST 数据, 所以现在表单为空。最好的解决方法是什么?我的解决方案:$('#myForm input[type=text]').keypress(function(e){if(e.which==13){e.preventDefault();$('#myForm').find('button[type=submit]').click();}}); - s3c
错误:$('#myForm').on('submit',function(e){e.preventDefault();$.ajax({...});});应为:$('#myForm').on('submit', function(e) { e.preventDefault(); $.ajax({ ... }); }); - s3c

2
当您在表单中指定了多个button时,如果它们没有指定type属性但具有较高的tabindex,则在触发button[type=submit]之前,将首先触发这些按钮中的第一个。因此,您应该为这些按钮添加type=button。例如:
<!-- inputs -->
<button type="button">action 1</button>
<button type="button">action 2</button>

<button type="submit">Submit form</button> <!-- With "Enter" this one will be triggered-->

0
此外,请确保表单中只有一个提交按钮。
即单个 <input type="submit"> 语句。
这适用于即使您使用 JavaScript 隐藏或显示它的情况。
如果由于某种原因您的表单中有多个提交按钮,则仅可使用 JavaScript 监听提交事件。

0

还有一个原因在其他答案中没有提到。

在Google Chrome(但不包括iOS Safari等),它会触发具有type="submit"的按钮和输入上的click事件,如果该事件上的任何处理程序调用preventDefault()(或在jQuery中使用return false;),则实际上会取消表单提交

因此,当您在聚焦于具有此类按钮的表单内的输入元素中按下<Return>时,请转到开发人员控制台并检查所有事件侦听器。逐个删除它们,然后尝试按<Return>。如果这解决了问题,则知道哪个事件处理程序使其出错。

我花了一个小时的时间来调试才意识到这一点!!


0
我还想补充一点,如果你有嵌套的<form>,那么只有直接在表单中的<input>会在按下回车键时触发提交,嵌套表单中的输入框不起作用。
<form submit="onSubmit">
 <input type="text" name="submits-on-enter" />
 <form submit="onSubmitNested">
    <input type="text" name="DOES-NOT-submit-on-enter" />
 </form>
 <button type="submit">SAVE</button>
</form>

如果您在投反对票,请好心告诉我为什么,谢谢。 - Luckylooke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接