【问题标题】:jquery how to catch enter key and change event to tabjquery如何捕获输入键并将事件更改为选项卡
【发布时间】:2011-01-21 02:08:48
【问题描述】:

我想要一个jquery的解决方案,我必须接近,需要做什么?

$('html').bind('keypress', function(e)
{
     if(e.keyCode == 13)
     {
         return e.keyCode = 9; //set event key to tab
     }
});

我可以返回 false 并且它会阻止按下 enter 键,我想我可以将 keyCode 更改为 9 以使其成为选项卡,但它似乎不起作用。我必须靠近,发生了什么事?

【问题讨论】:

  • 如何防止事件继续被上级处理,而不是尝试更改当前事件,发出新事件?
  • 由于安全原因修改 keyCode 是一个非常糟糕的主意,我很高兴最新的浏览器(IE11+ 也是)不支持这一点(但 IE 10 及更早版本确实支持这一点)。无论如何,在过去的两天里,我一直在为您的问题寻找最佳解决方案(这也是我的问题),在这里我发现了非常有趣的方法和解决方案实验。我仍在考虑最好的方法。

标签: jquery events keyevent


【解决方案1】:

Here is a solution :

$('input').on("keypress", function(e) {
            /* ENTER PRESSED*/
            if (e.keyCode == 13) {
                /* FOCUS ELEMENT */
                var inputs = $(this).parents("form").eq(0).find(":input");
                var idx = inputs.index(this);

                if (idx == inputs.length - 1) {
                    inputs[0].select()
                } else {
                    inputs[idx + 1].focus(); //  handles submit buttons
                    inputs[idx + 1].select();
                }
                return false;
            }
        });

【讨论】:

  • 那个解决方案对我来说看起来不太好。一方面,它不关注“tabindex”属性。此外,它特定于表单和输入元素,而(出于未知原因)原始提问者显然希望该效果在整个页面中是全局的。
  • @Pointy:这不是永恒的解决方案,希望从您或其他任何人那里看到其他可能性:)
  • 它可以解决问题,但我想看看其他人是否有不同的解决方案。
  • @payling:当然,这是更好的决定 :)
  • @Pointy 我知道问题被问到已经太久了,但你可能想看看我的答案;)
【解决方案2】:
$('input').live("keypress", function(e) {
            /* ENTER PRESSED*/
            if (e.keyCode == 13) {
                /* FOCUS ELEMENT */
                var inputs = $(this).parents("form").eq(0).find(":input:visible");
                var idx = inputs.index(this);

                if (idx == inputs.length - 1) {
                    inputs[0].select()
                } else {
                    inputs[idx + 1].focus(); //  handles submit buttons
                    inputs[idx + 1].select();
                }
                return false;
            }
        });

可见输入无法聚焦。

【讨论】:

    【解决方案3】:

    这是我的解决方案,欢迎反馈.. :)

    $('input').keydown( function (event) { //event==Keyevent
        if(event.which == 13) {
            var inputs = $(this).closest('form').find(':input:visible');
            inputs.eq( inputs.index(this)+ 1 ).focus();
            event.preventDefault(); //Disable standard Enterkey action
        }
        // event.preventDefault(); <- Disable all keys  action
    });
    

    【讨论】:

    • 但仍然得到一个丑陋的“警告:不应使用 keydown 事件的 'charCode' 属性......”。如果有人知道如何摆脱它... ;) Greez
    【解决方案4】:

    这很完美!

     $('input').keydown( function(e) {
            var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
            if(key == 13) {
                e.preventDefault();
                var inputs = $(this).closest('form').find(':input:visible');
                inputs.eq( inputs.index(this)+ 1 ).focus();
            }
        });
    

    【讨论】:

    • 它不适用于 Select 和表单外的文本字段。您能否修改它以适用于选择和表单外的任何字段。
    • @bjan 只需更改 jquery 选择器
    • 好但不完美。更好的是使用事件,因为它创建更少的事件处理程序(性能)并适用于 ajax 更新的 dom 对象 $('input').on("keypress", function(e) { ...
    • @AndzejMaciusovic,这完全是误导$('input').keydown(...$('input').on("keypress"... 的简写。他们都是一回事。你有证据吗?
    【解决方案5】:

    这些解决方案不适用于我的数据网格。我希望他们会。我真的不需要 Tab 或 Enter 来移动到下一个输入、列、行或其他任何内容。我只需要 Enter 来触发 .focusout 或 .change ,我的数据网格就会更新数据库。所以我将“enter”类添加到相关的文本输入中,这对我来说很有效:

    $(function() {
       if ($.browser.mozilla) {
            $(".enter").keypress(checkForEnter);
        } else {
            $(".enter").keydown(checkForEnter);
        }
    });
    
    function checkForEnter(event) {
        if (event.keyCode == 13) {
            $(".enter").blur();
        }
    }
    

    【讨论】:

      【解决方案6】:

      我将接受的答案中的代码作为 jQuery 插件编写,我发现它更有用。 (此外,它现在忽略隐藏、禁用和只读表单元素)。

      $.fn.enterAsTab = function () {
        $(this).find('input').live("keypress", function(e) {
          /* ENTER PRESSED*/
          if (e.keyCode == 13) {
              /* FOCUS ELEMENT */
              var inputs =   $(this).parents("form").eq(0).find(":input:visible:not(disabled):not([readonly])"),
                  idx = inputs.index(this);
      
              if (idx == inputs.length - 1) {
                  inputs[0].select()
              } else {
                  inputs[idx + 1].focus(); // handles submit buttons
                  inputs[idx + 1].select();
              }
              return false;
          }
        });
        return this;
      };
      

      这样我可以做到 $('#form-id').enterAsTab(); ...我想我会发布,因为还没有人将它作为 $ 插件发布,而且它们写起来并不完全直观。

      【讨论】:

      • 有类似的;几个月前发布了一个插件,看看我的回答。
      【解决方案7】:

      从 Ben 的插件构建,此版本处理选择,您可以将选项传递给 allowSubmit。 IE。 $("#form").enterAsTab({ 'allowSubmit': true}); 如果提交按钮正在处理事件,这将允许 enter 提交表单。

      (function( $ ){
          $.fn.enterAsTab = function( options ) {  
          var settings = $.extend( {
             'allowSubmit': false
          }, options);
          this.find('input, select').live("keypress", {localSettings: settings}, function(event) {
              if (settings.allowSubmit) {
              var type = $(this).attr("type");
              if (type == "submit") {
                  return true;
              } 
          }
          if (event.keyCode == 13 ) {
              var inputs =   $(this).parents("form").eq(0).find(":input:visible:not(disabled):not([readonly])");
              var idx = inputs.index(this);
              if (idx == inputs.length - 1) {
                 idx = -1;
             } else {
                 inputs[idx + 1].focus(); // handles submit buttons
            }
              try {
                  inputs[idx + 1].select();
                  }
              catch(err) {
                  // handle objects not offering select
                  }
              return false;
          }
      });
        return this;
      };
      })( jQuery );
      

      【讨论】:

      • 将禁用放入选择器中的括号[禁用]
      【解决方案8】:

      PlusAsTab:一个 jQuery 插件,使用数字键盘加键作为 Tab 键等效项。

      PlusAsTab 也是configurable to use the enter key as in this demo。见some of myolder answersto this question

      在您的情况下,将整个页面的输入键替换为选项卡功能(在选项中将输入键设置为选项卡之后)。

      <body data-plus-as-tab="true">
          ...
      </body>
      

      【讨论】:

      • 很好,乔尔!不过,处理 github 模块依赖项一开始让我陷入了困境。
      • @RiverC:是的,如果你忘记了子模块,它们可能会很棘手,尤其是使用 javascript 库。更新了文档以包含子模块,作为克隆建议。 git clone --recursive git://github.com/joelpurra/plusastab.git
      • 我喜欢Joel中的插件,但是使用“Enter As Tab”演示中提供的示例时,似乎无法识别tabindex。
      • @EdDeGagne:tabindex 被设计忽略 - 请参阅 SkipOnTab versus tabindex。可能应该写一些类似的东西或从 PlusAsTab 和 EmulateTab 链接到该页面。
      【解决方案9】:

      我充分利用了上述内容,并添加了处理任何输入、表单之外的功能等功能。如果您到达最后一个输入,它也会正确地循环返回以立即开始。如果只有一个输入,它会模糊然后重新聚焦单个输入以触发任何外部模糊/焦点处理程序。

      $('input,select').keydown( function(e) {
        var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
        if(key == 13) {
          e.preventDefault();
          var inputs = $('#content').find(':input:visible');
          var nextinput = 0;
          if (inputs.index(this) < (inputs.length-1)) {
            nextinput = inputs.index(this)+1;
          }
          if (inputs.length==1) {
            $(this).blur().focus();
          } else {
            inputs.eq(nextinput).focus();
          }
        }
      });
      

      【讨论】:

      • 这很好用,除了 textareas,它只是添加了一个换行符(这可能是故意的)。我没有测试收音机/复选框/选择。不过,我不想维护您的代码:可读性是一项要求:)。适当的间距和支撑有很长的路要走。
      【解决方案10】:

      为什么不做这样简单的事情?

      $(document).on('keypress', 'input', function(e) {
      
        if(e.keyCode == 13 && e.target.type !== 'submit') {
          e.preventDefault();
          return $(e.target).blur().focus();
        }
      
      });
      

      这样,除非您已经专注于“提交”的输入类型,否则您不会触发提交,并且它会将您放在您离开的地方。这也使它适用于动态添加到页面的输入。

      注意:对于可能有任何“on blur”事件侦听器的任何人,blur() 位于 focus() 之前。该过程不需要工作。

      【讨论】:

      • @versedi 我不认为这是准确的。你能解释一下你的意思吗?这应该在所有使用 jQuery 的操作系统和浏览器上都可以正常工作
      • 这是基于键盘键码,在您的情况下仅表示为 13。我们应该记住具有单独代码的小键盘 Enter 键 - Mac 中的 3(它不影响使用 13 的 Windows他们两个)。
      • 那么问题出在哪里?只需这样做(e.keyCode == 13) || (e.keyCode == 3 )
      • 最初的问题是将输入键行为更改为制表键行为,而不仅仅是捕捉按下的输入键。
      【解决方案11】:

      我知道这个问题比上帝更古老,但我从未见过如此优雅的答案。

      doc.on('keydown', 'input', function(e, ui) {
          if(e.keyCode === 13){
              e.preventDefault();
              $(this).nextAll('input:visible').eq(0).focus();
          }
      });
      

      这似乎可以用尽可能少的行完成工作。

      【讨论】:

      • 确实看起来很简单,但如果我是对的,请不要处理 textarea 和 disabled 。也许你想按照 Sarfraz 的建议保持目前的形式。
      【解决方案12】:

      这是我一直在使用的:

      $("[tabindex]").addClass("TabOnEnter");
      $(document).on("keypress", ".TabOnEnter", function (e) {
       //Only do something when the user presses enter
           if (e.keyCode == 13) {
                var nextElement = $('[tabindex="' + (this.tabIndex + 1) + '"]');
                console.log(this, nextElement);
                 if (nextElement.length)
                      nextElement.focus()
                 else
                      $('[tabindex="1"]').focus();
            }
      });
      

      注意tabindex不是针对表单而是针对整个页面的。

      注意 live 已被 jQuery 淘汰,现在您应该使用 on

      【讨论】:

      • 这是我最喜欢的答案。它在我的情况下效果很好,但应该注意的是,如果元素的 tabindex 不是连续的,它就不会。
      • 只有在元素上有 tabindex 时才有用,否则它不起作用。
      【解决方案13】:

      这终于完美地为我工作了。我正在使用 jqeasyui,它工作正常

      $(document).on('keyup', 'input', function(e) {
       if(e.keyCode == 13 && e.target.type        !== 'submit') {
         var inputs =   $(e.target).parents("form").eq(0).find(":input:visible"),
         idx = inputs.index(e.target);
             if (idx == inputs.length - 1) {
                inputs[0].select()
             } else {
                inputs[idx + 1].focus();
                inputs[idx + 1].select();
             }
       }
      
      });
      

      【讨论】:

      • 感谢 Metin 解决了我的问题,我为 select 添加了一点检查:$(document).on('keyup', 'input,select', function(e) {
      【解决方案14】:

      包括所有类型的输入

      $(':input').keydown(function (e) {
          var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
          if (key == 13) {
              e.preventDefault();
              var inputs = $(this).closest('form').find(':input:visible:enabled');
              if ((inputs.length-1) == inputs.index(this))
                  $(':input:enabled:visible:first').focus();
              else
                  inputs.eq(inputs.index(this) + 1).focus();
          }
      });
      

      【讨论】:

      • 这对我不起作用。我将所有内容设置为enabled="false",设置tabindex 顺序,当光标位于文本框中时按Enter 仍会触发默认操作(提交第一个按钮)。有什么改变会让我需要有所不同吗?我不知道我在 Jquery 中做什么,只是 asp.NET 和 VB.NET。
      • 查看控件是否在“form”标签中>>$(this).closest('form').length
      • 这个我最喜欢!我只是添加了一些小的改进:1).find(':input:visible:enabled[tabindex!="-1"]').not(':input[readonly]'); - 跳过只读和 tabindex=-1 字段...2)if (key == 13 &amp;&amp; $(this).attr('type') != 'submit') 排除提交按钮
      【解决方案15】:

      如果您使用的是 IE,这对我来说非常有用:

          <body onkeydown="tabOnEnter()">
          <script type="text/javascript">
          //prevents the enter key from submitting the form, instead it tabs to the next field
          function tabOnEnter() {
              if (event.keyCode==13) 
              {
                  event.keyCode=9; return event.keyCode 
              }
          }
          </script>
      

      【讨论】:

      • 抱歉,刚刚看到“jquery”部分
      • 它看起来很简单,但不幸的是在 IE11 上不起作用。它工作的最后一个版本是 IE10(我已经尝试过所有的 IE 仿真模式)
      【解决方案16】:

      您应该过滤所有禁用和只读元素。 我认为这段代码不应该涵盖按钮

      $('body').on('keydown', 'input, select, textarea', function(e) {
          var self = $(this),
              form = self.parents('form:eq(0)'),
              submit = (self.attr('type') == 'submit' || self.attr('type') == 'button'),
              focusable,
              next;
      
          if (e.keyCode == 13 && !submit) {
              focusable = form.find('input,a,select,button,textarea').filter(':visible:not([readonly]):not([disabled])');
              next = focusable.eq(focusable.index(this)+1);
      
              if (next.length) {
                  next.focus();
              } else {
                  form.submit();
              }
      
              return false;
          }
      });
      

      【讨论】:

        【解决方案17】:

        我在开发中也有同样的需求,所以我对此进行了研究。在过去的两天里,我阅读了许多文章并尝试了许多解决方案,例如 jQuery.tabNext() 插件。

        我在使用 IE11 时遇到了一些问题(所有 IE 版本都有这个 bug)。当输入文本后跟非文本输入时,选择不会被清除。因此,我根据@Sarfraz 解决方案建议创建了自己的 tabNext() 方法。我也在考虑它应该如何表现(仅以当前形式或通过完整文档圈出)。我仍然没有处理 tabindex 属性,主要是因为我偶尔使用它。但我不会忘记的。

        为了我的贡献可以轻松地对每个人有用,我在这里创建了 jsfiddle 示例https://jsfiddle.net/mkrivan/hohx4nes/

        我还在这里包含了示例的 JavaScript 部分:

                    function clearSelection() {
                    if (document.getSelection) { // for all new browsers (IE9+, Chrome, Firefox)
                        document.getSelection().removeAllRanges();
                        document.getSelection().addRange(document.createRange());
                        console.log("document.getSelection");
                    } else if (window.getSelection) { // equals with the document.getSelection (MSDN info)
                        if (window.getSelection().removeAllRanges) {  // for all new browsers (IE9+, Chrome, Firefox)
                            window.getSelection().removeAllRanges();
                            window.getSelection().addRange(document.createRange());
                            console.log("window.getSelection.removeAllRanges");
                        } else if (window.getSelection().empty) {  // maybe for old Chrome
                            window.getSelection().empty();
                            console.log("window.getSelection.empty");
                        }
                    } else if (document.selection) {  // IE8- deprecated
                        document.selection.empty();
                        console.log("document.selection.empty");
                    }
                }
                function focusNextInputElement(node) { // instead of jQuery.tabNext();
                    // TODO: take the tabindex into account if defined
                    if (node !== null) {
                        // stay in the current form
                        var inputs = $(node).parents("form").eq(0).find(":input:visible:not([disabled]):not([readonly])");
                        // if you want through the full document (as TAB key is working)
                        // var inputs = $(document).find(":input:visible:not([disabled]):not([readonly])");
                        var idx = inputs.index(node) + 1; // next input element index
                        if (idx === inputs.length) { // at the end start with the first one
                            idx = 0;
                        }
                        var nextInputElement = inputs[idx];
                        nextInputElement.focus(); //  handles submit buttons
                        try { // if next input element does not support select()
                            nextInputElement.select();
                        } catch (e) {
                        }
                    }
                }
                function tabNext() {
                    var currentActiveNode = document.activeElement;
                    clearSelection();
                    focusNextInputElement(currentActiveNode);
                }
                function stopReturnKey(e) {
                    var e = (e) ? e : ((event) ? event : null);
                    if (e !== null) {
                        var node = (e.target) ? e.target : ((e.srcElement) ? e.srcElement : null);
                        if (node !== null) {
                            var requiredNode = $(node).is(':input')
                                    // && !$(node).is(':input[button]')
                                    // && !$(node).is(':input[type="submit"]')
                                    && !$(node).is('textarea');
                            // console.log('event key code ' + e.keyCode + '; required node ' + requiredNode);
                            if ((e.keyCode === 13) && requiredNode) {
                                try {
                                    tabNext();
                                    // clearSelection();
                                    // focusNextInputElement(node);
                                    // jQuery.tabNext();
                                    console.log("success");
                                } catch (e) {
                                    console.log("error");
                                }
                                return false;
                            }
                        }
                    }
                }
                document.onkeydown = stopReturnKey;
        

        我也留下了注释行,以便可以遵循我的想法。

        【讨论】:

        • 我要非常感谢本主题的所有贡献者。没有你,我将无法为我的开发问题创造最好的结果。我的解决方案是整合你所有的测试,当然还有一些插件。
        【解决方案18】:

        我知道这已经很老了,但我一直在寻找相同的答案,发现选择的解决方案不遵守 tabIndex。因此,我将其修改为以下对我有用的内容。请注意,maxTabNumber 是一个全局变量,用于保存可选项卡输入字段的最大数量

          $('input').on("keypress", function (e) {
                        if (e.keyCode == 13) {
                            var inputs = $(this).parents("form").eq(0).find(":input");
                            var idx = inputs.index(this);
        
                            var tabIndex = parseInt($(this).attr("tabindex"));
                            tabIndex = (tabIndex + 1) % (maxTabNumber + 1);
                            if (tabIndex == 0) { tabIndex = 1; }
                            $('[tabindex=' + tabIndex + ']').focus();
                            $('[tabindex=' + tabIndex + ']').select();
                  
                            return false;
                        }
            });

        【讨论】:

          【解决方案19】:

          这是我编写的一个 jQuery 插件,它处理回车键作为回调或制表键(带有可选回调):

          $(document).ready(function() {
            $('#one').onEnter('tab');
            $('#two').onEnter('tab');
            $('#three').onEnter('tab');
            $('#four').onEnter('tab');
            $('#five').onEnter('tab');
          });
          
          /**
           * jQuery.onEnter.js
           * Written by: Jay Simons
           * Cloudulus.Media (https://code.cloudulus.media)
           */
          
          if (window.jQuery) {
              (function ($) {
                  $.fn.onEnter = function (opt1, opt2, opt3) {
                      return this.on('keyup', function (e) {
                          var me = $(this);
                          var code = e.keyCode ? e.keyCode : e.which;
                          if (code == 13) {
                              if (typeof opt1 == 'function')
                              {
                                  opt1(me, opt2);
                                  return true;
                              }else if (opt1 == 'tab')
                              {
                                  var eles = $(document).find('input,select,textarea,button').filter(':visible:not(:disabled):not([readonly])');
                                  var foundMe = false;
                                  var next = null;
                                  eles.each(function(){
                                      if (!next){
                                          if (foundMe) next = $(this);
                                          if (JSON.stringify($(this)) == JSON.stringify(me)) foundMe = true;
                                      }
                                  });
                                  next.focus();
                                  if (typeof opt2 === 'function')
                                  {
                                      opt2(me, opt3);
                                  }
                                  return true;
                              }
                          }
                      }).on('keydown', function(e){
                          var code = e.keyCode ? e.keyCode : e.which;
                          if (code == 13)
                          {
                              e.preventDefault();
                              e.stopPropagation();
                              return false;
                          }
                      });
                  }
              })(jQuery);
          } else {
              console.log("onEnter.js: This class requies jQuery > v3!");
          }
          input,
          select,
          textarea,
          button {
            display: block;
            margin-bottom: 1em;
          }
          <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
          <form>
            <input id="one" type="text" placeholder="Input 1" />
            <input id="two" type="text" placeholder="Input 2" />
          
            <select id="four">
              <option selected>A Select Box</option>
              <option>Opt 1</option>
              <option>Opt 2</option>
            </select>
            <textarea id="five" placeholder="A textarea"></textarea>
            <input id="three" type="text" placeholder="Input 3" />
            <button>A Button</button>
          </form>

          【讨论】:

            【解决方案20】:

            我只需要进入下一步即可输入和选择,并且元素必须是可聚焦的。这个脚本更适合我:

            $('body').on('keydown', 'input, select', function(e) {
                if (e.key === "Enter") {
                    var self = $(this), form = self.parents('form:eq(0)'), focusable, next;
                    focusable = form.find('input,select,textarea').filter(':visible');
                    next = focusable.eq(focusable.index(this)+1);
                    if (next.length) {
                        next.focus();
                    } else {
                        form.submit();
                    }
                    return false;
                }
            });
            

            也许它对某人有帮助。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-07-18
              • 2011-04-08
              • 1970-01-01
              • 2012-08-14
              • 1970-01-01
              • 2011-10-28
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多