jQuery如何捕捉回车键并将事件更改为Tab键?

76

我需要一个jQuery的解决方案,我觉得已经接近了,还需要做什么?

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

我可以返回false并防止按下回车键,我以为只需要将keyCode更改为9就可以将其变成制表符,但似乎行不通。我已经接近了答案,发生了什么事?


防止事件继续由上层处理,而不是尝试更改当前事件,发出一个新事件怎么样? - Spidey
由于安全原因,修改 keyCode 是非常不好的想法,我很高兴最新版本的浏览器(包括 IE11)不再支持这个功能(但 IE10 及更早版本支持此功能)。无论如何,在过去的两天里,我一直在寻找最好的解决方案来回答你的问题(这也是我的问题),在这里我找到了非常有趣的方法和解决方案实验。尽管如此,我仍在思考最佳途径。 - Miklos Krivan
20个回答

78

这里有一个解决方案:

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

7
我不认为那个解决方案很好。首先,它没有考虑到“tabindex”属性。另外,它只适用于表单和输入元素,而(原问题的提问人)显然想要在整个页面范围内全局生效(出于未知原因)。 - Pointy
1
@Pointy:这不是永久解决方案,很想看到你或其他人的其他可能性 :) - Sarfraz
@Pointy 我知道这个问题问得已经很久了,但你可能想要看一下我的回答 ;) - Kamran Ahmed
live已被jQuery正式“废弃”,现在您必须使用on。请查看我的答案,了解如何使用on实现它 ;) - Kamran Ahmed
@Sarfraz我无法解决如何利用tab index的问题,其中enter键被更改为tab场景。我在下面发布了一个Q链接,任何帮助都将不胜感激http://stackoverflow.com/questions/38489379/enter-key-as-tab-to-follow-the-tabindex 。 - user5249203
显示剩余4条评论

34

这个完美运作!

 $('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
它无法为选择器和表单之外的文本字段工作。您能否将其修改为同时适用于选择器和表单之外的任何字段? - bjan
2
@bjan 只需更改 jQuery 选择器即可。 - Leandro Bardelli
好,但不完美。更好的方法是使用事件绑定,因为它创建较少的事件处理程序(提高性能),并且适用于 Ajax 更新的 DOM 对象。$('input').on("keypress", function(e) { ... - Andzej Maciusovic
2
@AndzejMaciusovic,这是完全误导性的。$('input').keydown(...$('input').on("keypress"... 的简写形式。它们是一样的东西。你有证据吗? - azerafati

10

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

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

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

});

这样,除非您已经将焦点集中在“提交”输入类型上,否则不会触发提交,而且它会把您带回到离开的地方。这还使其适用于动态添加到页面上的输入。

注意:对于任何可能具有“失去焦点”事件侦听器的人,blur()位于focus()之前。这不是必要的过程。


@versedi 我不认为那是准确的。你能解释一下你的意思吗?只要使用jQuery的所有操作系统和浏览器都可以完美地工作。 - rpearce
这是基于键盘按键代码的,你的情况下只有13。我们应该记住数字小键盘上的回车键有单独的代码 - 在 Mac 上为 3(这不会影响使用 13 的 Windows)。 - versedi
那么问题在哪里?只需要这样做:(e.keyCode == 13) || (e.keyCode == 3) - Risinek
最初的问题是将回车键行为更改为制表键行为,而不仅仅是捕获按下的回车键。 - Miklos Krivan

7

PlusAsTab:一个 jQuery 插件,将数字键盘上的加号键作为 Tab 键的等效键。

PlusAsTab 还可以进行配置,以使用回车键,就像此演示中所示。请参见我的一些较早的答案对于这个问题

在您的情况下,在选项中将回车键设置为 Tab 功能后,将整个页面替换为 Tab 功能。

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

非常好,Joel!不过一开始处理github模块依赖关系让我有些困惑。 - user1086498
@RiverC:是的,如果你忘记了子模块,那么它们可能会很棘手,尤其是在使用Javascript库时。已更新文档以包含子模块,作为克隆建议。git clone --recursive git://github.com/joelpurra/plusastab.git - Joel Purra
我喜欢Joel插件,但是当使用“Enter As Tab”演示中提供的示例时,它似乎无法识别tabindex。 - Ed DeGagne
@EdDeGagne:tabindex是被设计忽略的 - 请参见SkipOnTab versus tabindex。应该从PlusAsTab和EmulateTab编写类似的内容或链接到该页面。 - Joel Purra

5
从Ben的插件开始,这个版本处理了选择并且你可以传递一个选项来允许提交。例如:$("#form").enterAsTab({ 'allowSubmit': true}); 如果提交按钮正在处理事件,这将允许按回车键提交表单。
(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 );

将禁用状态放入选择器的方括号中 [disabled]。 - Miklos Krivan

5

以下是我一直在使用的内容:

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

注意live已被jQuery弃用,现在应该使用on要注意tabindex,并且不仅仅是针对表单,而是整个页面。


这是我最喜欢的答案。它在我的情况下运行良好,但需要注意的是,如果元素的tabindex不是连续的,则无法正常工作。 - Josh Bilderback
只有在元素上设置tabindex时,它才有效。否则它不起作用。 - 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(); ...。考虑到还没有人将其作为$插件发布,而且编写起来也不是很直观,所以我决定发布这篇文章。

有类似的东西;几个月前发布了一个插件,可以看看我的回答。 - Joel Purra

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

});

谢谢Metin,您解决了我的问题,我添加了一个小的选择检查:$(document).on('keyup', 'input,select', function(e) { - user3086295

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顺序,但是当光标在文本框中时按下回车键仍会触发默认操作(提交第一个按钮)。是否有任何更改使得这对我需要有所不同?我对Jquery一无所知,只熟悉asp.NET和VB.NET。 - pixelmeow
看看控件是否在“form”标签中
$(this).closest('form')。长度
- pmereles
1
这个我最喜欢!我只是加了一些小改进:1).find(':input:visible:enabled[tabindex!="-1"]').not(':input[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'属性。如果有人知道如何摆脱它... ;)问候 - Nick Ma.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接