停止回车键提交表单

5
我有一个表格位于一个表单中。该表格包含一些表单字段,但表格之外还有一些表单字段(但仍在表单内)。
我知道通过键盘使用Enter和Return通常用于提交表单,但我想停止表格内字段的此行为。例如,如果我聚焦于表格内的一个字段并按下Enter/Return,则不会发生任何事情。如果我聚焦于表格之外的一个字段(但仍在表单内),则会正常提交。
我有一个针对此表格的jQuery插件。简而言之,这是我迄今所尝试过的:
base.on('keydown', function(e) {
    if (e.keyCode == 13) {
        e.stopPropagation();
        return false;
    }
});

base 是 jQuery 对象中的表格对象。这段代码位于我的插件的 init 方法中。然而,按下回车键仍会提交表单。

我在哪里出错了?

编辑: 一些简化的 HTML:

<form method="" action="">
  <input type="text" /><!--this should still submit on Enter-->
  <table>
    <tbody>
      <tr>
        <td>
          <input type="text" /><!--this should NOT submit on Enter-->
        </td>
      </tr>
    </tbody>
  </table>
</form>

1
可能是 https://dev59.com/m3I_5IYBdhLWcg3wBuNs 和 https://dev59.com/NnNA5IYBdhLWcg3wmfO5 的重复问题。 - Mark Walters
你应该说明 base 是什么,它看起来像是一个 jQuery 对象,但它不遵循 命名约定 - gdoron
@gdoron 我看过了。这是第一个代码块后的第一句话!“其中base是jQuery对象表格”。 - Martin Bean
@MartinBean。抱歉,但命名约定是您真正想要遵循的事情。对我愚蠢的行为感到抱歉。 - gdoron
@gdoron 正如我所说,JavaScript 被简化了,但 base 名称来自于这个插件的起源:http://starter.pixelgraphics.us/ - Martin Bean
6个回答

9
base.keypress(function(e) {
    var code = e.keyCode || e.which;
    if(code == 13)
        return false;
});

或仅限于输入:
$(':input', base).keypress(function(e) {
    var code = e.keyCode || e.which;
    if(code == 13)
        return false;
});

1
请重新阅读问题。我仍然希望在我的表格之外的表单控件上工作默认行为。 - Martin Bean
当按下回车键时,您需要检查表格中的任何元素(输入)是否处于焦点状态。 - Mark Walters
@gdoron 我能不能直接从我的插件中实现这个功能,而不是从表单下手呢?例如,我不希望它适用于任何带有表格的表单输入。 - Martin Bean
@gdoron 我想要停止在应用了我的插件的表格中提交输入,而不仅仅是在带有输入的表单中的任何表格。 - Martin Bean
@MartinBean。那么我的更新答案应该已经解决了这个问题,不是吗? - gdoron
1
太好了,最终成功了。我将我的 keyup 事件名称更改为 keypress,现在我拥有了所需的功能。谢谢! - Martin Bean

3
我猜测一个表单元素将触发提交事件,它不会通过表格并到达表单,尝试使用以下方法代替:
$('input, select, textarea', base).on('keydown', function(e) {
    if (e.keyCode == 13) {
        return false;
    }
});

请注意,我们还向选择器提供了上下文,因此这个 keyDown 只会在您的表格中的元素(根据需要进行修改)上发生。
正如戈登在另一个评论中所说,返回 false 同时执行 .preventDefault().stopPropagation()

你需要将选择器限制在表单\表格内的输入框中。实际上是gdoron而不是gordan... :) - gdoron
这就是选择器中第二个参数 base 的作用,其中 base 是我的表格作为 jQuery 对象。 - Martin Bean
糟糕,我的名字写错了:P,但它是限制于表格的,因为“base”是表格对象。 - Ben Everard

2

e.preventDefault()e.stopPropagation()更好。stopPropagation只能阻止事件冒泡到更高的DOM节点,但它不能防止默认操作。


return false 会同时执行它们... - gdoron
如果我的代码中有return false,为什么表单仍然会提交? - Martin Bean
不是针对您个人,但尽管此答案已获得赞同,它是错误的。return false == e.preventDefault(); e.stopPropagation(); - gdoron
我认为你也需要重新考虑一下你的答案,gdoron。你的答案会针对任何表格中的任何表单,而我只想针对我的插件应用到的表格中的输入进行操作。 - Martin Bean

1
我发现了这个问答,试图解决一个类似的情况,即我有多个表单,但按下回车键并不能实现我想要的功能。在我的特定情况下,我会动态添加一个新的<div id="D1">,例如D1、D2、D3等,每个新的div都有一个表单,该表单将从创建它的同一php代码重新加载该div,只是还带有POST。
不相关的第一个问题是我无法动态创建一个新的函数来处理每个div,因此我将D1等描述符作为参数传递给Javascript函数。
<script type="text/javascript">
function formSubmit ( divid ) {
    // post data
    event.preventDefault();
    $.post( "make-my-form-div.php", 
            $("#form"+divid).serialize(), 
            function(data){
                $("#"+divid).html(data);
            });
    return false;
}
</script>

你会看到必要的event.preventDefault();return false;在这个线程的答案中起作用。但对我没用。如果我点击任何一个表单中的提交按钮,那个 div 会重新加载正确的数据。按回车键将导致默认操作并重新加载整个页面,留下我只有一个 div。 这个答案有效:我需要不同表单的唯一 ID 和 NAME。最初,它们是<INPUT TYPE="button" VALUE="Submit" onClick="formSubmit('<?php echo $divid ?>');">但是一旦我添加了唯一的ID和NAME,例如“formD1”等,它就开始正常工作了。

0

这对我有用。

$("input[type='text']").on('keypress', function(e) { return e.keyCode != 13; });

0

只需将以下代码放入您的模板文件或页面头部即可。

<script type="text/javascript">

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

document.onkeypress = stopRKey;

</script> 

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