输入触发器按钮单击

Posted

技术标签:

【中文标题】输入触发器按钮单击【英文标题】:Enter triggers button click 【发布时间】:2011-06-13 09:56:02 【问题描述】:

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

我找不到任何看起来像设置默认按钮的可靠方法的方法,我现在也不一定想要这样做。在没有更好的情况下,我已经在表单的任何位置捕获了一个按键,如果按下的是 <Enter> 键,我只是否定它:

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

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

据我目前所知,它似乎有效,但感觉非常笨拙。

有谁知道这样做的更复杂的技术吗?

同样,这个解决方案有什么我不知道的陷阱吗?

谢谢。

【问题讨论】:

在使用 Angular 反应形式时也会发生这种情况,不仅对 JQuery 有用,对 Angular 开发也有用。 【参考方案1】:

默认情况下,在表单的文本字段中按 enter 将提交表单。如果您不希望它以这种方式工作,您必须捕获输入键并像您所做的那样使用它。没有办法解决这个问题。即使表单中没有按钮,它也会以这种方式工作。

【讨论】:

我认为问题不在于表单提交,而是它触发按钮元素上的click 操作希望是一个意外结果 你是对的。无论哪种方式,结果都是一样的 - 您必须捕获回车键以防止不必要的表单提交。【参考方案2】:

我会这样做:在按钮的 onclick 事件(不是提交)的处理程序中检查事件对象的键码。如果是“输入”,我会返回 false。

【讨论】:

那个键码总是像点击一样被传递。问题就在于此。 :-) 那我猜你做的很难——同时处理按钮上的 onkeydown 事件。处理程序将被传递一个 keyEvent;检查 keyCode -> if 13, preventDefault。这样,您实际上也可以让用户在该按钮上按下回车键,而不会产生执行点击事件的副作用。【参考方案3】:

您可以使用 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>

按下回车键仍会触发表单提交,但 javascript 会阻止它实际提交,直到您实际按下按钮。

【讨论】:

【参考方案4】:

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

HTML5 spec explicitly states what happens in implicit submissions:

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

如果用户代理支持让用户隐式提交表单(例如,在某些平台上,当文本字段被聚焦时按下“enter”键会隐式提交表单),那么对于默认按钮具有定义的激活行为必须使用户代理在该默认按钮上运行合成点击激活步骤。

这在 HTML4 规范中没有明确说明,但是浏览器已经实现了 HTML5 规范中描述的内容(这就是明确包含它的原因)。

编辑添加:

我能想到的最简单的答案是将您的提交按钮作为表单中的第一个[type="submit"] 项目,使用css在表单底部添加填充,并将提交按钮绝对定位在您的底部会喜欢的。

【讨论】:

我在诅咒 IE,原来是我一直草率的标记!干杯! 哇...谢谢你的好先生。这是一个偶然的发现。我什至无法理解为什么点击回车键会触发点击事件,但您的引用将我引向w3.org/TR/html5/forms.html#implicit-submission 链接已损坏。我认为w3c.github.io/html/sec-forms.html#implicit-submission 是新网址。【参考方案5】:

通过在焦点 &lt;input type="text"&gt; 上按“Enter”,您会在第一个定位元素上触发“点击”事件:&lt;button&gt;&lt;input type="submit"&gt;。如果您在&lt;textarea&gt; 中按“Enter”,则只需新建一个文本行。

参见示例here。

您的代码阻止在&lt;textarea&gt; 中创建新的文本行,因此您必须仅捕获&lt;input type="text"&gt; 的按键。

但是为什么你需要在文本字段中按Enter?如果您想通过按“Enter”提交表单,但&lt;button&gt; 必须在布局中保持在第一位,只需使用标记:将&lt;input type="submit"&gt; 代码放在&lt;button&gt; 之前并使用CSS 保存您的布局需要。

捕捉 'Enter' 并保存标记:

$('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 失败。 :)【参考方案6】:

我认为您不需要 javascript 或 CSS 来解决此问题。

根据html 5 spec for buttons,没有类型属性的按钮被视为与类型设置为“提交”的按钮相同,即作为提交其包含表单的按钮。将按钮的类型设置为“按钮”应该会阻止您看到的行为。

我不确定浏览器对此的支持,但html 4.01 spec for buttons 中指定了相同的行为,所以我希望它非常好。

【讨论】:

【参考方案7】:

使用

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

应该可以解决问题。

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

【讨论】:

太好了,谢谢,对于我来说,这就像 IE8 中的按钮捕获 点击,type="button" 似乎解决了这个问题......谢谢! p.s.知道为什么会这样吗? ie8 将按钮视为类型提交?很奇怪。 好答案,这会向浏览器提示哪些按钮不是提交按钮,因此它可以在不重新排序标记的情况下做正确的事情。 @Leinster 的回答涵盖了这个怪癖的原因 - “没有类型属性的按钮被视为与类型设置为提交的按钮相同。” 同样适用于&lt;input type="submit"/&gt;(会触发点击)和&lt;input type="button"/&gt;(不会触发点击) 难以置信!!我很困惑。【参考方案8】:

我添加了一个“提交”类型的按钮作为表单的第一个元素,并使其不可见 (width:0;height:0;padding:0;margin:0;border-style:none;font-size:0;)。就像网站的刷新一样,即按下按钮时我什么都不做,除非网站再次加载。对我来说效果很好......

【讨论】:

【参考方案9】:

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

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

我找到了设置默认按钮here的答案:

<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>

没有使用任何脚本,我使用&lt;button&gt; form="bla" 属性定义了每个按钮所属的表单。我将Delete 按钮设置为一个不存在的表单,并将我想在Enter 键上触发的Update 按钮设置为用户在输入文本时将处于的表单。

到目前为止,这是唯一对我有用的东西。

【讨论】:

请查看how to answer on ***【参考方案10】:

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(),其他按钮会被触发。

【讨论】:

【参考方案11】:

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

【讨论】:

这应该被接受为正确答案。 这是解决我问题的关键,谢谢!【参考方案12】:

你可以这样做。

将您的事件绑定到一个通用函数中,并通过按键或按钮单击来调用该事件。

例如。

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




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

【讨论】:

以上是关于输入触发器按钮单击的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在输入单击和按钮上触发 jQuery datepicker 元素?

单击“重力形式”输入按钮时触发 jquery

抑制触发的 Blazor 输入事件

除了单击按钮之外,如何在 jQuery 中触发模糊?

vb中单击命令按钮触发哪些事件

除了单击按钮之外,如何在jQuery中触发模糊?