使用回车键防止表单提交

59

我刚刚写了这个漂亮的小函数,可以在表单本身上使用...

$("#form").keypress(function(e) {
    if (e.which == 13) {
        var tagName = e.target.tagName.toLowerCase(); 
        if (tagName !== "textarea") {
            return false;
        }
    }
});

在我的逻辑中,我想要在文本区域输入期间接受回车符。此外,如果能够将输入字段的回车键行为替换为定位到下一个输入字段的行为(就像按下标签键一样),那将是额外的奖励。有人知道如何使用事件传播模型,在适当的元素上正确触发回车键,但防止表单在其按下时提交吗?


13
我刚意识到在KeyUp事件中我返回了false,而不是在可以阻止提交回发的KeyPress事件中。为避免其他人出现与我同样的问题,我想提一下这个问题。 - Kenneth J
1
你缺少结尾的)。 - Robbie Smith
以及结尾的分号 ; - Stack Underflow
10个回答

54

您可以模拟按下Tab键而不是Enter键来操作输入框,代码如下:

//Press Enter in INPUT moves cursor to next INPUT
$('#form').find('.input').keypress(function(e){
    if ( e.which == 13 ) // Enter key = keycode 13
    {
        $(this).next().focus();  //Use whatever selector necessary to focus the 'next' input
        return false;
    }
});

当按下Enter键时,显然您需要确定哪些选择器是必要的,以便将焦点集中在下一个输入上。


需要添加 -- return false; - Craig
我喜欢你用“return false”来阻止整个输入。应将“return false”移入条件块中。否则应使用“return true”。 - pronebird
我该怎么避免光标聚焦在只读输入字段上,比如跳过只读字段? - Aitazaz Khan
1
@AitazazKhan,你可以使用“tabindex”属性,但我认为你的光标最终仍然会到达它。你也可以在只读输入框聚焦时设置一个jQuery事件,并将焦点强制转移到另一个元素... 我从未尝试过这样做。 - Jake Wilson
1
你可能会发现 $(this).nextAll('INPUT').first().focus();$(this).next().focus(); 更适合。试一试,看看它们的区别。 - Volomike

40

请注意,单个输入表单在按下回车键时总是会提交。唯一的防止这种情况发生的方法是:

<form action="/search.php" method="get">
<input type="text" name="keyword" />
<input type="text" style="display: none;" />
</form>

4
谢谢你的小费:单输入表格在按下回车键时会自动提交。 - Vipul
1
绝对精彩! - Muhammad Ali

27

这是我修改后的函数版本,它执行以下操作:

  1. 防止回车键在表单中的任何元素上起作用,除了文本区域、按钮和提交按钮。
  2. 现在回车键的作用类似于制表符。
  3. 在元素上调用preventDefault()、stopPropagation()是可以的,但在表单上调用会停止事件传递到元素。

因此,我的解决方法是检查元素类型,如果类型不是textarea(允许输入回车)、button/submit(回车=点击),那么我们就切换到下一个元素。

在元素上调用.next()没有用,因为其他元素可能不是简单的同级元素,但由于DOM在选择时几乎保证顺序,所以一切都很好。

function preventEnterSubmit(e) {
    if (e.which == 13) {
        var $targ = $(e.target);

        if (!$targ.is("textarea") && !$targ.is(":button,:submit")) {
            var focusNext = false;
            $(this).find(":input:visible:not([disabled],[readonly]), a").each(function(){
                if (this === e.target) {
                    focusNext = true;
                }
                else if (focusNext){
                    $(this).focus();
                    return false;
                }
            });

            return false;
        }
    }
}

如果不清楚的话,preventEnterSubmit是表单keypress事件的处理程序。 - Álvaro González
如果您能添加选择支持,那将更好。 - Aitazaz Khan
由于某种原因,我就是无法让它工作。jQuery('#form_id').onkeypress(preventEnterSubmit(e); 返回一个引用错误,说找不到e;使用更迂回的方法也一样,例如jQuery('#form_id').addEventListener('keypress', preventEnterSubmit(e));这里缺少什么? - Kaji

5

从可用性角度来看,将回车行为改为模仿制表符是一个非常糟糕的想法。用户习惯使用回车键提交表单。这就是互联网的工作方式。你不应该打破这一点。


10
并非一定每次都需要强制使用制表符。如果已经很清楚需要填写另一个字段,那么强制使用制表符是可以的,只要确实需要填写下一个字段即可。 - 700 Software
10
如果您使用条形码扫描器,它们在发送完条形码号码后会自动发送回车键。 - bestattendance
2
而且......Safari在你手动尝试从列表中进行选择时使用回车键来选择,这很糟糕,但这就是它的做法。 - Ghoti
我总体上同意这个观点,但是这也是我在这里的原因……我有一个包括添加地图点的表单,我不希望使用邮政编码搜索的用户意外提交表单(地图搜索字段也保存为表单的一部分,所以我不能完全删除它),有时候需要打破规则的情况。 - Toni Leigh
我发现用户对这种行为感到惊讶。而且,jQuery验证与输入键提交不起作用。 - nuander
如果您有一个多步骤表单,其中一次只在一系列“屏幕”中显示一个表单输入,则用户可能希望按回车键进入下一个屏幕。 - V. Rubinetti

3

《Enter Key as the Default Button》一文介绍了如何设置Enter键的默认行为。然而,有时您需要禁用在按下Enter键时提交表单。如果您想完全防止这种情况,您需要在页面的<form>标签上使用OnKeyPress处理程序来禁用表单提交。

<body OnKeyPress="return disableKeyPress(event)">

JavaScript代码应该是这样的:
<script language="JavaScript">

function disableEnterKey(e)
{
     var key;      
     if(window.event)
          key = window.event.keyCode; //IE
     else
          key = e.which; //firefox      

     return (key != 13);
}

</script>

如果你想在输入框按下回车键时禁用表单提交,你必须在输入框的OnKeyPress处理程序中使用上述函数,如下所示:
<input type="text" name="txtInput" onKeyPress="return disableEnterKey(event)">

来源: http://www.bloggingdeveloper.com/post/Disable-Form-Submit-on-Enter-Key-Press.aspx

本文介绍了如何使用jQuery禁用表单在按下回车键时自动提交。您可以通过捕获回车键事件并取消默认行为来实现这一点。此外,该文章还提供了一个完整的代码示例,以便更好地理解如何实现此功能。

这是对我来说唯一有效的解决方案。我的情况是使用自动填充选项进行编辑,当您选择选项并按回车键时,对吧?在我的情况下,所选选项未传递到js函数,而是提交了表单。现在我可以使用Google地图API以及这个小的阻止技巧。它对谷歌浏览器也完全有效。谢谢。 - Yevgeniy Afanasyev
@YevgeniyAfanasyev 很高兴你觉得我的解决方案有帮助 :) - MA9H

1

我稍微修改了Dmitriy Likhten答案,效果很好。包括如何将函数引用到事件中。请注意,不要包含(),否则它会被执行。我们只是传递一个引用。

$(document).ready(function () {
    $("#item-form").keypress(preventEnterSubmit);
});

function preventEnterSubmit(e) {
    if (e.which == 13) {
        var $targ = $(e.target);

        if (!$targ.is("textarea") && !$targ.is(":button,:submit")) {
            var focusNext = false;
            $(this).find(":input:visible:not([disabled],[readonly]), a").each(function () {
                if (this === e.target) {
                    focusNext = true;
                } else {
                    if (focusNext) {
                        $(this).focus();
                        return false;
                    }
                }
            });

            return false;
        }
    }
}

0

之前的解决方案对我没有用,但我找到了一个解决方案。

这个方法等待任何按键,测试是否匹配13,如果是则返回false。

在<HEAD>标签中

function stopRKey(evt) {
  var evt = (evt) ? evt : ((event) ? event : null);
  var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
  if ((evt.which == 13) && (node.type == "text")) {
    return false;
  }
}

document.onkeypress = stopRKey;

0

我更喜欢@Dmitriy Likhten的解决方案,但是:只有当我稍微改变了代码时它才起作用:

[...] else 
            { 
             if (focusNext){
                $(this).focus();
                return false; } //  
            }     

否则脚本无法工作。 使用Firefox 48.0.2。

0
在我的情况下,我只想防止在动态创建的字段中进行操作,并激活其他一些按钮,因此它有点不同。
$(document).on( 'keypress', '.input_class', function (e) {
    if (e.charCode==13) {
        $(this).parent('.container').children('.button_class').trigger('click');
        return false;
    }
});

在这种情况下,它将捕获具有该类的所有输入的回车键,并触发它们旁边的按钮,还会防止提交主表单。
请注意,输入和按钮必须位于同一个容器中。

-1

为表单和输入设置触发器,但当触发输入事件时,通过调用stopPropagation方法停止传播到表单。

顺便说一句,在我看来,改变默认行为不是一个好主意,因为这会让用户在使用您的系统时感到愤怒。但如果您坚持要这样做,那么stopPropagation方法就是正确的选择。


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