Jquery 如何捕获输入键并将事件更改为 tab

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

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

我可以返回 false,它可以防止回车键被按下,我想我可以只改变 keyCode 为9,使它标签,但它似乎不工作。我得靠近点,怎么回事?

156929 次浏览

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

visible input cann't be focused.

This is my solution, feedback is welcome.. :)

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

This works perfect!

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

These solutions didn't work with my datagrid. I was hoping they would. I don't really need Tab or Enter to move to the next input, column, row or whatever. I just need Enter to trigger .focusout or .change and my datagrid updates the database. So I added the "enter" class to the relevant text inputs and this did the trick for me:

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


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

I wrote the code from the accepted answer as a jQuery plugin, which I find more useful. (also, it now ignores hidden, disabled, and readonly form elements).

$.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;
};

This way I can do $('#form-id').enterAsTab(); ... Figured I'd post since no one has posted it as a $ plugin yet and they aren't entirely intuitive to write.

Building from Ben's plugin this version handles select and you can pass an option to allowSubmit. ie. $("#form").enterAsTab({ 'allowSubmit': true}); This will allow enter to submit the form if the submit button is handling the event.

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

PlusAsTab: A jQuery plugin to use the numpad plus key as a tab key equivalent.

PlusAsTab is also configurable to use the enter key as in this demo. See some of my older answers to this question.

In your case, replacing the enter key with tab functionality for the entire page (after setting the enter key as tab in the options).

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

I took the best of the above and added the ability to work with any input, outside of forms, etc. Also it properly loops back to start now if you reach the last input. And in the event of only one input it blurs then refocuses the single input to trigger any external blur/focus handlers.

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

Why not something simple like this?

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


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


});

This way, you don't trigger the submit unless you're focused on the input type of "submit" already, and it puts you right where you left off. This also makes it work for inputs which are dynamically added to the page.

Note: The blur() is in front of the focus() for anyone who might have any "on blur" event listeners. It is not necessary for the process to work.

I know this question is older than god, but I never saw an answer that was all that elegant.

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

that seems to get the job done in as few lines as humanly possible.

Here is what I've been using:

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

Pays attention to the tabindex and is not specific to the form but to the whole page.

Note live has been obsoleted by jQuery, now you should be using on

This is at last what is working for me perfectly. I am using jqeasyui and it is working fine

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


});

Includes all types of inputs

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

If you're using IE, this worked great for me:

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

you should filter all disabled and readonly elements. i think this code should not cover buttons

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

I had the same requirement in my development so I did research on this. I have read many articles and tried many solutions during last two days like jQuery.tabNext() plugin.

I had some trouble with IE11 (all IE version has this bug). When an input text followed by non text input the selection was not cleared. So I have created my own tabNext() method based on @Sarfraz solution suggestion. I was also thinking on how it should behave (only circle in the current form or maybe through the full document). I still did not take care of the tabindex property mostly because I am using it occasionally. But I will not forget it.

In order to my contribution can be useful for everybody easily I have created jsfiddle example here https://jsfiddle.net/mkrivan/hohx4nes/

I include also the JavaScript part of the example here:

            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;

I left commented rows as well so my thinking can be followed.

I know this is rather old, but I was looking for the same answer and found that the chosen solution did not obey the tabIndex. I have hence modified it to the following which works for me. Please note that maxTabNumber is a global variable that holds the maximum number of tabbable input fields

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

Here's a jQuery plugin I wrote that handles enter key as a callback or as a tab key (with an optional callback):

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

I need to go next only to input and select, and element have to be focusable. This script works better for me:

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

Maybe it helps someone.