输入触发器按钮单击


168

我有一个带有两个按钮的页面。一个是<button>元素,另一个是<input type="submit">。按钮按此顺序显示在页面上。如果我在表单中任意位置的文本字段中,然后按<Enter>click则触发按钮元素的事件。我认为那是因为button元素位于第一个位置。

我找不到任何看起来像是设置默认按钮的可靠方法的东西,在这一点上我也不一定想要。在没有更好的方法的情况下,我在窗体上的任何地方都捕获了按键,并且,如果它是<Enter>被按下的键,那么我就是在否定它:

$('form').keypress( function( e ) {
  var code = e.keyCode || e.which;

  if( code === 13 ) {
    e.preventDefault();
    return false; 
  }
})

据我所知,它似乎正在工作,但感觉很难受。

有谁知道更复杂的技术来做到这一点?

同样,我只是不知道该解决方案有什么陷阱?

谢谢。


1
当使用角度反应形式时,也会发生这种情况,不仅对JQuery有用,而且对角度开发也有用。
HDJEMAI

Answers:


362

使用

<button type="button">Whatever</button>

应该可以。

原因是因为表单内的按钮的类型隐式设置为submit。作为zzzzBoz说,规范说,第一buttoninputtype="submit"是什么在这种情况下触发。如果您专门设置了type="button",则浏览器会将其从考虑中删除。


1
亲爱的,谢谢,似乎是IE8中的按钮让我捕获了<enter>点击,type="button"似乎可以解决此问题...谢谢!ps关于这是为什么的任何想法?ie8将按钮视为提交类型?奇怪的。
Quang Van

3
好的答案,这向浏览器暗示了哪些按钮不是提交按钮,因此它可以做正确的事情而无需重新排列标记。
Don Spaulding

2
@Leinster的答案涵盖了此怪癖的原因-“没有类型属性的按钮与设置为要提交的类型的按钮一样。”
存储桶

2
同样适用于<input type="submit"/>(将触发点击)和<input type="button"/>(将不会触发点击)
MariusBalčytis2014年

1
难以置信的!!我很困惑。
Margus Pala

54

阅读HTML规范以真正了解预期的行为很重要:

HTML5规范明确规定在发生的事情implicit submissions

表单元素的默认按钮是树形顺序中的第一个提交按钮,其表单所有者是该表单元素。

如果用户代理支持让用户隐式提交表单(例如,在某些平台上,当文本字段集中隐式提交时,按下“ enter”键提交表单),则对默认按钮具有定义的激活的表单执行此操作行为必须导致用户代理在该默认按钮上运行综合点击激活步骤。

在HTML4规范中并未对此进行明确说明,但是浏览器已经在实现HTML5规范中所描述的内容(这就是为什么将其明确包含在内)的原因。

编辑添加:

我能想到的最简单的答案是将您的“提交”按钮作为[type="submit"]表单中的第一项,使用CSS将填充添加到表单的底部,然后将“提交”按钮绝对定位在所需的底部。


在那里,我在诅咒IE,结果一直都是我的草率标记!干杯!
肖森

2
哇...谢谢你,先生。这是一个偶然的发现。我什至无法理解为什么按下回车键会引发点击事件,但是您的引用使我进入了w3.org/TR/html5/forms.html#implicit-submission
2014年

链接断开。我认为w3c.github.io/html/sec-forms.html#implicit-submission是新的网址。
TJ。

22

我认为您不需要JavaScript或CSS即可解决此问题。

根据html 5的按钮规范,无类型属性的按钮与类型设置为“提交”的按钮被视为相同,即作为提交其包含表单的按钮。将按钮的类型设置为“按钮”应该可以防止您看到的行为。

我不确定浏览器对此是否支持,但是在html 4.01规范中为按钮指定了相同的行为,因此我希望它相当不错。


13

通过在焦点上按“ Enter”,<input type="text">您将在第一个定位的元素上触发“ click”事件:<button><input type="submit">。如果在中按“ Enter”键<textarea>,则只需新建一个文本行。

请参阅此处的示例。

您的代码阻止在其中输入新的文本行<textarea>,因此您只需要按键即可<input type="text">

但是,为什么需要Enter在文本字段中按?如果您想按“ Enter”键提交表单,但<button>必须在布局中排在首位,只需使用标记:将<input type="submit">代码放在之前,<button>并使用CSS保存所需的布局。

捕捉“输入”并保存标记:

$('input[type="text"]').keypress(function (e) {
    var code = e.keyCode || e.which;
    if (code === 13)
    e.preventDefault();
    $("form").submit(); /*add this, if you want to submit form by pressing `Enter`*/
});

if语句不应该只有在按下enter键时才执行两个语句吗?否则,每次按键都会进行提交。提醒我goto失败。:)
danmiser 2014年

13

<button>默认情况下,无论您在哪里使用元素,它都会考虑该按钮,type="submit"因此,如果定义该按钮,type="button"则不会将其<button>视为提交按钮。


2

默认情况下,在表单的文本字段中按Enter键将提交表单。如果您不希望它那样工作,则必须捕获Enter键并像完成操作一样使用它。这是没有办法的。即使表单中没有按钮,它也将以这种方式工作。


4
我不认为问题在于提交表单,而是触发click了按钮元素上的操作,这是意想不到的结果
Martin Jespersen

你是对的。无论哪种方式,结果都是相同的-您必须捕获Enter键以防止不必要的表单提交。
Sparafusile 2011年

2

您可以使用javascript阻止表单提交,直到适当的时候为止。一个非常粗糙的例子:

<form onsubmit='return false;' id='frmNoEnterSubmit' action="index.html">

    <input type='text' name='txtTest' />

    <input type='button' value='Submit' 
        onclick='document.forms["frmNoEnterSubmit"].onsubmit=""; document.forms["frmNoEnterSubmit"].submit();' />

</form>

按下Enter仍会触发表单提交,但是javascript会阻止它实际提交,直到您实际按下按钮为止。


2

Dom示例

  <button onclick="anotherFoo()"> Add new row</button>
  <input type="text" name="xxx" onclick="foo(event)">

javascript

function foo(event){
   if(event.which == 13 || event.keyCode == 13) // for crossbrowser
   {
     event.preventDefault(); // this code prevents other buttons triggers use this
     // do stuff
   }
}

function anotherFoo(){
  // stuffs.
}

如果不使用preventDefault(),则会触发其他按钮。


0

我将按照以下方式进行操作:在按钮的onclick事件(不提交)的处理程序中,检查事件对象的键码。如果是“输入”,我将返回false。


该键码总是像单击一样被传递。问题就出在这里。:-)
Rob Wilkerson,

然后,我想您很难做到这一点-还要处理按钮上的onkeydown事件。处理程序将被传递一个keyEvent; 检查keyCode->如果为13,则为preventDefault。这样,您实际上就可以让用户在该按钮上按下Enter键,而不会执行click事件。
Satyajit

0

我的情况Submit在form元素中有两个按钮:UpdateDelete。该Delete按钮删除图像,并且该Update按钮使用表单中的文本字段更新数据库。

因为Delete按钮是表单中的第一个按钮,所以它是键上的默认按钮Enter。不是我想要的 用户希望能够Enter在更改某些文本字段后进行点击。

我找到了在此处设置默认按钮的答案:

<form action="/action_page.php" method="get" id="form1">
  First name: <input type="text" name="fname"><br>
  Last name: <input type="text" name="lname"><br>
</form>
<button type="submit" form="form1" value="Submit">Submit</button>

在不使用任何脚本的情况下,我使用<button> form="bla"属性定义了每个按钮所属的形式。我将Delete按钮设置为不存在的表单,并将要在键上Update触发的按钮设置Enter为用户在输入文本时将要使用的表单。

到目前为止,这是对我唯一有效的方法。



0

你可以做这样的事情。

将事件绑定到通用函数中,然后通过按键或单击按钮来调用事件。

例如。

function callME(event){
    alert('Hi');
}



$('button').on("click",callME); 
$('input ').keypress(function(event){
  if (event.which == 13) {
    callME(event);
  }
});

-1

我添加了一个“ submit”类型的按钮作为表单的第一个元素,并使它不可见(width:0;height:0;padding:0;margin:0;border-style:none;font-size:0;)。就像刷新站点一样工作,即按下按钮时我什么也没做,只是重新加载了站点。对我来说很好...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.