jQuery如何捕获Enter键并将事件更改为Tab


74

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

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

我可以返回false,它可以防止按下Enter键,我以为可以将keyCode更改为9使其成为选项卡,但它似乎不起作用。我必须接近,这是怎么回事?


阻止该事件继续由上级层处理,而不是尝试更改当前事件,而是发出新事件,该怎么办?
Spidey

出于安全原因,修改keyCode并不是一个好主意,我很高兴最新的浏览器(也就是IE11 +)不支持此功能(但IE 10和更早的版本支持此功能)。无论如何,在过去两天里我一直在寻找最佳解决方案(也是我的问题),在这里我发现了非常有趣的方法和解决方案实验。我仍然在考虑最好的方法。
Miklos Krivan '17

Answers:


77

这是一个解决方案:

$('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;
            }
        });

6
该解决方案在我看来并不那么好。一方面,它不关注“ tabindex”属性。而且,它特定于表单和输入元素,而(由于未知原因)原始发问者显然希望该效果在整个页面上都是全局的。
尖尖的

1
@Pointy:这不是永恒的解决方案,希望您或其他任何人看到其他可能性:)
Sarfraz

它可以解决问题,但我想看看是否还有其他人有不同的解决方案。
10年

@payling:当然,这是个更好的决定:)
Sarfraz

@Pointy我知道问了问题已经很久了,但是您可能想看看我的回答;)
Kamran Ahmed

33

这很完美!

 $('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();
        }
    });

2
它不适用于“选择”和表单外的文本字段。您能否将其修改为既适用于选择内容又适用于表单以外的任何字段。
2012年

2
@bjan只是更改了jquery选择器
Leandro

不错,但是不完美。最好使用event on,因为它创建较少的事件处理程序(性能)并为ajax更新的dom对象工作($('input')。on(“
keypress

2
@AndzejMaciusovic,这是完全误导$('input').keydown(...是速记$('input').on("keypress"...。他们都是同一回事。你有证明吗?
azerafati

9

为什么不这样简单?

$(document).on('keypress', 'input', function(e) {

  if(e.keyCode == 13 && e.target.type !== 'submit') {
    e.preventDefault();
    return $(e.target).blur().focus();
  }

});

这样,除非您已经专注于“ submit”的输入类型,否则您不会触发提交,这样您就可以从上次停下来的位置开始。这也使其适用于动态添加到页面的输入。

注意:对于可能具有任何“模糊”事件侦听器的任何人,blur()都位于focus()的前面。该过程没有必要进行。


@versedi我认为那是不正确的。您能解释一下您的意思吗?这在使用jQuery的所有操作系统和浏览器上都可以正常运行
rpearce 2015年

这基于键盘按键代码,在您的情况下仅表示为13。我们应该记住有关numpad Enter键的问题,该按键具有单独的代码-在Mac中为3(这并不影响同时使用13的Windows)。
versedi

所以有什么问题?就是这样做(e.keyCode == 13) || (e.keyCode == 3 )
Risinek '16

最初的问题是将Enter键行为更改为Tab键行为,而不仅仅是捕获按下的Enter键。
Miklos Krivan '17

7

PlusAsTab:一个jQuery插件,用于将numpad加号用作Tab键。

如本演示中所示, PlusAsTab也可以配置为使用Enter键。请参阅 对这个问题的一些较早答案

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

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

很好,乔尔!不过,起初,处理github模块依赖项使我陷入了循环。

@RiverC:是的,如果忘记子模块,尤其是使用JavaScript库,子模块可能会很棘手。更新了文档,以包括子模块作为克隆建议。git clone --recursive git://github.com/joelpurra/plusastab.git
乔尔·普拉

我喜欢Joel中的插件,但似乎使用“ Enter As Tab”演示中提供的示例时,它无法识别tabindex。
Ed DeGagne 2013年

@EdDeGagne:tabindex被设计忽略-请参见SkipOnTab与tabindex。应该可以从PlusAsTab和EmulateTab编写类似的内容或链接到该页面。
乔尔·普拉

5

此版本从Ben的插件构建,可以处理select,您可以传递一个选项allowSubmit。即。$("#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 );

将禁用项置于选择器的括号中[禁用]
Miklos Krivan

4

我从接受的答案中将代码编写为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(); ...想出我要发布,因为还没有人将其发布为$插件,而且编写起来也不是很直观。


有类似的东西。几个月前发布了一个插件,请参阅我的答案。
乔尔·普拉

4

终于这对我来说是完美的。我正在使用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();
       }
 }

});

谢谢梅丁,您解决了我的问题,我为select添加了一点点检查:$(document).on('keyup','input,select',function(e){
user3086295 2013年

4

这是我一直在使用的:

$("[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


这是我最喜欢的答案。在我的情况下,它运行良好,但应注意,如果元素的tabindexs不是顺序的,则不会。
乔什·比尔德巴克

仅当元素上具有tabindex时,它才是好的,否则它将不起作用。
Miklos Krivan '17

3

包括所有类型的输入

$(':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。
pixelmeow 2015年

查看控件是否在“ form”标签中>> $(this).closest('form')。length
pmereles 2015年

1
我最喜欢的那个!我刚刚添加了一些小的改进:1).find(':input:visible:enabled[tabindex!="-1"]').not(':input[readonly]');-跳过readonly和tabindex = -1字段... 2)if (key == 13 && $(this).attr('type') != 'submit')排除提交按钮
Rustam Guliev

2

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

$('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
Nick Ma。

2

我充分利用了上述优点,并增加了使用任何输入(表格之外的内容)的功能。如果到达最后一个输入,它也可以正确循环回到现在开始。在只有一个输入的情况下,它会模糊然后重新聚焦单个输入以触发任何外部模糊/焦点处理程序。

$('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之外,该方法工作正常,它仅添加换行符(可能是有意的)。我没有测试单选/复选框/选择。但是,我不想维护您的代码:可读性是必需的:)。适当的间距和撑杆很长的路要走。
modle13

1

这些解决方案不适用于我的datagrid。我希望他们会。我真的不需要Tab键或Enter键即可移至下一个输入,列,行或其他内容。我只需要输入Enter即可触发.focusout或.change,而我的datagrid会更新数据库。因此,我在相关的文本输入中添加了“ enter”类,这为我实现了窍门:

$(function() {
   if ($.browser.mozilla) {
        $(".enter").keypress(checkForEnter);
    } else {
        $(".enter").keydown(checkForEnter);
    }
});

function checkForEnter(event) {
    if (event.keyCode == 13) {
        $(".enter").blur();
    }
}

0
$('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;
            }
        });

可见输入无法聚焦。


0

我知道这个问题比上帝还古老,但是我从来没有见过这么优雅的答案。

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

这似乎可以在尽可能少的范围内完成工作。


看起来真的很简单,但是如果我是对的话,不要打理textarea并禁用它。也许您希望按照Sarfraz建议的方式保持当前状态。
Miklos Krivan '17

0

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

$('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;
    }
});

0

我在开发中有相同的要求,因此我对此进行了研究。最近两天,我读了许多文章并尝试了许多解决方案,例如jQuery.tabNext()插件。

我在IE11上遇到了一些麻烦(所有IE版本都有此错误)。当输入文本后接非文本输入时,未清除选择。因此,我根据@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;

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


我要对这个主题的所有贡献者表示非常感谢。没有你,我将无法为我的发展问题创造最佳结果。我的解决方案是将您所有人与许多测试以及一些附加组件集成在一起。
Miklos Krivan '17

0

我知道这已经很老了,但是我在寻找相同的答案,发现选择的解决方案没有遵循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;
                }
    });


0

这是我写的一个jQuery插件,用于将Enter键作为回调或Tab键(带有可选的回调)进行处理:

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


0

我只需要输入和选择内容,元素必须是可聚焦的。这个脚本对我来说更好:

$('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;
    }
});

也许对某人有帮助。


-1

如果您使用的是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”部分
frustratedInFresno

它看起来真的很简单,但不幸的是在IE11上不起作用。可以使用的最新版本是IE10(我已经尝试了所有IE仿真模式)
Miklos Krivan
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.