如何捕获在包含多个表单的页面上按下的输入键?

我继承了一个 Web 应用程序,其中在任何输入字段中按回车键的常用功能已被禁用,原因是页面包含多个表单,并且应用程序无法确定(或者,因此我被告知)采取哪种形式.应用程序的设计没有提交按钮(如 input type="submit"),相反,设计人员已经进行了 onclick 处理.这是在其中一个页面上定义的两个按钮,用于说明

I have inherited a web application where the usual ability to press return in any of the input fields has been disabled for the very good reason that the page contains multiple forms, and the application would not be able to determine (or, so I am told) which form to action. The application has been designed so there are no submit buttons (as in input type="submit") and, instead, the designers have gone for onclick handling. Here are two buttons that are defined on one of the pages, included for illustration

<input type="button" value="LOGIN"  name="btnLoginOk" onclick="submit(); />"

<input type="button" class="button-click-grey" value="Find Link Partners"  
    onclick="raiseEvent('SubmitForm','',this);" style="cursor:pointer;" />

但我真的希望能够让用户在他们愿意的情况下按回车键,例如如果他们刚刚输入了与 LOGIN 关联的字段,则检测到并执行 onclick="submit();"

But I really want to be able to allow users to press return if they wish e.g. if they've just typed into a field associated with the LOGIN, then detect that and action the onclick="submit();"

也许 jQuery 有一个解决方案.

Perhaps there is a solution with jQuery.

推荐答案

页面包含多个表单,并且应用程序将无法确定(或者,我被告知)哪个付诸行动.

page contains multiple forms, and the application would not be able to determine (or, so I am told) which form to action.

当您在输入控件上按 Enter 时,浏览器会在该表单中寻找第一个提交按钮 并模拟点击它.在多个按钮的情况下,第一个将在键盘输入时按下(这绝不是一成不变的,浏览器可能会偏离这一点).

When you press enter on an input control the browser seeks the first submit button in that form and simulates a click on it. In the case of multiple buttons, the first one will be pressed on keyboard enter (this is by no means written in stone and browsers may deviate from this).

如果您有两个表单,则获得按键的表单将 这是第一个提交按钮被按下.因此,您实际上并不需要对此进行任何特殊处理.你只需要停止挡路.

If you have two forms, the one that got a keypress will have it's first submit button pressed. Therefore you don't really need any special handling of this. You just have to stop being in the way.

您可以在代码中的表单上模拟这一点:

You can simulate this in code, on a form:

 $( 'form' ).bind('keypress', function(e){
   if ( e.keyCode == 13 ) {
     $( this ).find( 'input[type=submit]:first' ).click();
   }
 });

或窗口(用于演示大致发生的情况):

Or window (for a demonstration of what is roughly happening):

 $( window ).bind('keypress', function(e){
   if ( $( e.originalTarget ).is( ':input' ) && e.keyCode == 13 ) {
     $(  e.originalTarget )
       .closest( 'form' )
         .find( 'input[type=submit]:first' )
           .click();
   }
 });

当然假设 .preventDefault() 没有被事件调用.

Assuming of course that .preventDefault() has not been called on the event.

底线:如果你有这个事件,你可以从中推断出它来自什么元素,因此它属于哪种形式.即使在这种情况下:

Bottom line: If you have the event you can divine from it what element it came from and therefore which form it belongs to. Even in this case:

<input type="button" value="LOGIN" name="btnLoginOk" onclick="submit();">

这里 submit() 是一个全局函数,但是当它被调用时,它的上下文 (this) 将是元素,你可以这样做 submit(e){ this.form.submit();}.

Here submit() is a global function, but when it is called, its context (this) will be the element and you may do submit(e){ this.form.submit(); }.

应用程序的设计没有提交按钮(如输入type="submit") ,相反,设计师已经进行了 onclick 处理.

The application has been designed so there are no submit buttons (as in input type="submit") and, instead, the designers have gone for onclick handling.

在我看来,这听起来像是设计者没有完全理解 DOM/表单事件,并且正在解决这个问题.另一个可能的原因可能是程序很旧,并且是在这些东西不像今天那样稳定或没有正确记录的时候重新设计的.

This sounds to me like the designer doesn't fully comprehend DOM / form events and is going the long way around the problem. Another likely reason could be that the program is old and was designed back when these things weren't quite as stable, or properly documented, as they are today.

替换这个:

<form action="/login/" method="POST">
  [...]
  <input type="button" value="LOGIN" name="btnLoginOk" onclick="submit();">
</form>

有了这个:

<form action="/login/" method="POST">
  [...]
  <input type="submit" value="LOGIN" name="btnLoginOk">
</form>

然后为所有需要它的表单添加一个键处理程序,如果满足某些条件,它会检测并禁止输入(对于您确实想要禁用它的表单).

Then add a key handler to all forms that need it, that detects and suppresses enter if some condition is met (for the forms that you actually do want to disable this on).

// for all forms that POST that have 2+ submit buttons
$( 'form[method=post]:has(:submit:eq(1))' ).bind('keydown', function(e){
  // if target is an enter key, input element, and not a button
  if ( e.keyCode == 13 && e.target.tagName == 'INPUT' && 
       !/^(button|reset|submit)$/i.test( e.target.type ) ) {
    return false;  // kill event
  }
});

或者更好的是:使用知道如何为您执行此操作的表单验证库(或 jQuery 插件).

Or better still: Use a form validation library (or jQuery plugin) that knows how to do this for you.

相关文章