如何防止按下回车键提交Web表单?

228

如何防止在基于Web的应用程序中按下ENTER键提交表单?

30个回答

103

[修订 2012年,无内联处理程序,保留文本区域回车处理]

function checkEnter(e){
 e = e || event;
 var txtArea = /textarea/i.test((e.target || e.srcElement).tagName);
 return txtArea || (e.keyCode || e.which || e.charCode || 0) !== 13;
}

现在你可以在表单上定义一个按键处理程序:
<form [...] onkeypress="return checkEnter(event)">

document.querySelector('form').onkeypress = checkEnter;

3
顺便说一下:您可以在checkEnter函数中通过事件来源添加对输入类型的检查,以排除文本区域。 - KooiInc
1
可以用。我把它添加到单个输入框中,因为我想避免按下回车键提交表单。它有一个按钮来执行内部搜索,实际上提高了可用性。 - Foxinni
1
使用此函数与表单作为整体的事件处理程序的一个问题是,它还会阻止在表单中也存在的文本区域中发生回车(通常是希望出现回车)。 - Lonnie Best
1
@LonnieBest:感谢您的关注。您确实阅读了我在此答案上的评论(请参见上文),是吗?无论如何,我已经修订了这个相当陈旧的答案。 - KooiInc
我注意到这会防止在提交按钮上聚焦时按下回车键。我们该如何解决这个问题? - Jonathan
1
@Jonathan:你可以将处理程序附加到单个输入字段或包含一组输入字段(但不包括按钮)的某个 div 上,而不是整个表单。 - KooiInc

58

以下是一个jQuery处理程序,可用于阻止回车提交和后退键->后退。在“keyStop”对象中的(keyCode:selectorString)对用于匹配不应触发其默认操作的节点。

请记住,网络应该是一个无障碍的地方,这会打破键盘用户的期望。尽管如此,在我的情况下,我正在工作的Web应用程序也不喜欢返回按钮,因此禁用其快捷键是可以的。 “应该输入 - >提交”讨论很重要,但与实际提问的问题无关。

以下是代码,由您思考可访问性以及为什么要这样做!

$(function(){
 var keyStop = {
   8: ":not(input:text, textarea, input:file, input:password)", // stop backspace = back
   13: "input:text, input:password", // stop enter = submit 

   end: null
 };
 $(document).bind("keydown", function(event){
  var selector = keyStop[event.which];

  if(selector !== undefined && $(event.target).is(selector)) {
      event.preventDefault(); //stop event
  }
  return true;
 });
});

12
最简单的方法是:$("#myinput").keydown(function (e) { if(e.which == 13) e.preventDefault(); });关键是同时使用 "keydown" 和 event.preventDefault() 。它不能与 "keyup" 一起使用。 - lepe
这种解决方案的优点在于,与其他仅阻止键13的解决方案不同,浏览器的自动建议功能将继续正常工作。 - jsalvata
你正在每次按键时访问keyStop数组:这样不好。 我会写成 if(event.which in keyStop)...,而不是访问一个未定义的属性, 或者更好的方式是: 添加第一行代码:if(event.which in keyStop === false) return; - Nadir

55

只需从onsubmit处理程序中返回false即可。

<form onsubmit="return false;">
或者如果您想在中间使用一个处理程序。
<script>
var submitHandler = function() {
  // do stuff
  return false;
}
</script>
<form onsubmit="return submitHandler()">

5
这似乎是最简单的答案。我在谷歌浏览器上尝试了一下,它运行良好。你在每个浏览器中都测试过吗? - styfle
25
如果你希望通过点击“提交”按钮来提交表格,那么这不是一个好主意。 - AliBZ
15
无法工作,因为提交按钮不再提交表单。 - paullb
48
@Paul,这个为什么会得到38个赞?完全阻止 <form> 的提交就像是连婴儿一起倒掉。 - Pacerier
9
在单页面应用程序(SPA)的情况下,你几乎总是希望手动处理表单提交。在这种情况下,始终阻止浏览器提交表单(并刷新页面,重新启动应用程序)是合理的做法。 - Nathan Friend
显示剩余7条评论

46
//Turn off submit on "Enter" key

$("form").bind("keypress", function (e) {
    if (e.keyCode == 13) {
        $("#btnSearch").attr('value');
        //add more buttons here
        return false;
    }
});

5
这个方法很好用。使用e.preventDefault()而不是return false可以达到同样的效果,但允许事件传递到父元素的处理程序。默认操作(表单提交)仍将被阻止。 - willscripted

25
您需要调用此函数,它会取消表单的默认提交行为。您可以将其附加到任何输入字段或事件上。
function doNothing() {  
var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
    if( keyCode == 13 ) {


    if(!e) var e = window.event;

    e.cancelBubble = true;
    e.returnValue = false;

    if (e.stopPropagation) {
        e.stopPropagation();
        e.preventDefault();
    }
}

2
e 应该是一个参数,然后你应该检查 window.event。同时,你应该从事件中获取 keycode。最后,你应该返回 false。 - ntownsend
11
请问您能否说明在哪里以及如何调用这个函数? - mydoghasworms

19

短而简单的回答是使用纯Javascript:

<script type="text/javascript">
    window.addEventListener('keydown', function(e) {
        if (e.keyIdentifier == 'U+000A' || e.keyIdentifier == 'Enter' || e.keyCode == 13) {
            if (e.target.nodeName == 'INPUT' && e.target.type == 'text') {
                e.preventDefault();
                return false;
            }
        }
    }, true);
</script>

这只是禁用了 type='text' 的输入框中的 "Enter" 按键行为。访问者仍然可以在整个网站上使用 "Enter" 键。

如果您想禁用其他操作的 "Enter" 键,可以添加 console.log(e)进行测试,并在 Chrome 中按 F12,在“控制台”选项卡中单击页面上的“退格”并查看内部以查看返回的值,然后您可以针对所有这些参数来进一步改进上述代码以适应您需要的 "e.target.nodeName"、"e.target.type" 等等...

在此处查看我对类似问题的详细答案


4
实际上应该是 e.target.nodeName === 'INPUT' && e.target.type !== 'textarea'。使用指定的代码,如果聚焦在单选框或复选框上,它将允许提交表单。 - afnpires
1
这是最有效和资源友好的解决方案。感谢@AlexandrePires!这是我的完整工作脚本:https://dev59.com/nWgv5IYBdhLWcg3wPOfz#40686327 - eapo
1
唯一可行的解决方案;至少在我的情况下是这样。 - hex494D49

18

按下回车键只会激活表单的默认提交按钮,该按钮通常是表单中第一个可提交的按钮。

<input type="submit" />

浏览器会在表单内查找提交按钮。

因此,不需要一个提交按钮,而是像这样的内容

<input type="button" value="Submit" onclick="submitform()" /> 

编辑:根据评论讨论:

如果您只有一个文本字段,则此方法无法使用 - 但在这种情况下可能是期望的行为。

另一个问题是,此方法依赖JavaScript提交表单。这可能从可访问性角度来看是个问题。可以通过使用javascript编写<input type='button'/>,然后将<input type='submit' />放置在<noscript>标记中来解决这个问题。这种方法的缺点是对于禁用了javascript的浏览器,您将在按ENTER时进行表单提交。对于此情况下的期望行为,由OP决定。

我不知道在不涉及javascript的情况下如何实现此操作。


如果只有一个字段,这在Firefox中无法正常工作,这很奇怪。 - DanSingerman
6
对于无障碍性可能有影响?或许。然而它确实回答了那个人的问题,这也是 SO 的目的所在...或许在答案中进行编辑以指出无障碍性问题是一个很好的折衷方案? - Neil Barnwell
1
@bobince - 或许这个问题因为可访问性问题应该被评为-1,但这个回答准确吗?我不这么认为。此外,有一些合法的使用情况需要这样做。 - DanSingerman
你不需要使表单在没有 JavaScript 的情况下无法提交。但如果它确实起作用的话,也没用,因为浏览器会默认提交不包含提交按钮的表单。 - bobince
2
在所有这些浏览器中进行了测试,包括Opera,使用一个文本输入和一个输入按钮:所有浏览器都会在按下Enter键时提交表单。显然,您需要JavaScript来“解决”Enter键问题,但诀窍是在JS不可用的情况下完成操作而不使页面完全无法使用。 - bobince
显示剩余2条评论

16

过去我总是用类似上面的按键处理程序来完成它,但今天找到了一个更简单的解决方案。回车键只会触发表单上第一个非禁用的提交按钮,所以实际上需要拦截尝试提交的那个按钮:

<form>
  <div style="display: none;">
    <input type="submit" name="prevent-enter-submit" onclick="return false;">
  </div>
  <!-- rest of your form markup -->
</form>

就是这样。按键将像往常一样由浏览器/字段等处理。如果触发了回车提交逻辑,那么浏览器将找到隐藏的提交按钮并触发它。然后,JavaScript 处理程序将防止提交。


3
通常我不喜欢使用hack,但这个真的很有效。 - TechWisdom
4
只需在输入框上加入 hidden 属性,而不是删除 div 标签,这样会更短。不错的技巧 :) - Nik

9

我在这个主题中找到的所有答案,无论是在这里还是在其他帖子中,都有一个缺点,那就是它也会阻止表单元素实际更改触发。因此,如果您运行这些解决方案,onchange事件也不会被触发。为了克服这个问题,我修改了这些代码,并为自己开发了以下代码。我希望这对他人有用。我给我的表单加了一个class名叫"prevent_auto_submit",并添加了以下JavaScript:

$(document).ready(function() 
{
    $('form.prevent_auto_submit input,form.prevent_auto_submit select').keypress(function(event) 
    { 
        if (event.keyCode == 13)
        {
            event.preventDefault();
            $(this).trigger("change");
        }
    });
});

5
我已经花了一些时间,将这个程序跨浏览器适配到IE8、9、10、Opera 9+、Firefox 23、Safari(PC)和Safari(MAC)。 JSFiddle示例:http://jsfiddle.net/greatbigmassive/ZyeHe/ 基础代码 - 通过将“onkeypress”附加到您的表单并将“window.event”传递给它来调用此函数。
function stopEnterSubmitting(e) {
    if (e.keyCode == 13) {
        var src = e.srcElement || e.target;
        if (src.tagName.toLowerCase() != "textarea") {
            if (e.preventDefault) {
                e.preventDefault();
            } else {
                e.returnValue = false;
            }
        }
    }
}

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