input按键的行为就像在Javascript中的一个选项卡

我正在寻找创build一个表单按下input键导致焦点转到页面上的“下一个”表单元素。 我在网上find的解决scheme是…

<body onkeydown="if(event.keyCode==13){event.keyCode=9; return event.keyCode}"> 

不幸的是,似乎只能在IE浏览器中工作。 所以这个问题的真正含义是,如果有人知道一个适用于FF和Chrome的解决scheme? 此外,我宁愿不必将onkeydown事件添加到表单元素本身,但如果这是唯一的方法,它将不得不这样做。

这个问题类似于问题905222 ,但在我看来,这是它自己的问题。

编辑:另外,我也看到人们提出这个问题,这是不好的风格,因为它与用户习惯的forms行为不同。 我同意! 这是一个客户端请求:(

你可以用编程的方式迭代表单元素,并随时添加onkeydown处理函数。 这样你可以重用代码。

我用了Andrew提出的逻辑非常有效。 这是我的版本:

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

映射[Enter]键就像[Tab]键一样工作

我已经改写了Andre Van Zuydam的回答,这在jQuery中并不适合我。 这个上限同时inputShift + Enter 。 向前input标签,然后按住Shift + Enter标签。

我也重写了self被当前重点项目初始化的方式。 表格也是这样select的。 代码如下:

 // Map [Enter] key to work like the [Tab] key // Daniel P. Clark 2014 // Catch the keydown for the entire document $(document).keydown(function(e) { // Set self as the current item in focus var self = $(':focus'), // Set the form by the current item in focus form = self.parents('form:eq(0)'), focusable; // Array of Indexable/Tab-able items focusable = form.find('input,a,select,button,textarea,div[contenteditable=true]').filter(':visible'); function enterKey(){ if (e.which === 13 && !self.is('textarea,div[contenteditable=true]')) { // [Enter] key // If not a regular hyperlink/button/textarea if ($.inArray(self, focusable) && (!self.is('a,button'))){ // Then prevent the default [Enter] key behaviour from submitting the form e.preventDefault(); } // Otherwise follow the link/button as by design, or put new line in textarea // Focus on the next item (either previous or next depending on shift) focusable.eq(focusable.index(self) + (e.shiftKey ? -1 : 1)).focus(); return false; } } // We need to capture the [Shift] key and check the [Enter] key either way. if (e.shiftKey) { enterKey() } else { enterKey() } }); 

textarea的原因

被包括是因为我们“ ”要插入它。 另外,一旦进入,我们不想停止input新行的Enter的默认行为。

原因和button

允许默认的操作,“ ”仍然关注下一个项目,是因为他们不总是加载另一个页面。 对手风琴或标签内容等可能有触发/效果。 所以一旦你触发了默认的行为,并且页面做了特殊的效果,你仍然想要去下一个项目,因为你的触发器可能已经很好的介绍了它。

谢谢你的好脚本。

我刚刚在上面的函数中添加了shift事件以返回元素之间,我以为有人可能需要这个。

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

这为我工作

  $(document).on('keydown', ':tabbable', function (e) { if (e.which == 13 || e.keyCode == 13 ) { e.preventDefault(); var $canfocus = $(':tabbable:visible') var index = $canfocus.index(document.activeElement) + 1; if (index >= $canfocus.length) index = 0; $canfocus.eq(index).focus(); } }); 

的jsfiddle

这里给出的所有实现都有问题。 有些不能正确使用textareas和提交button,大多数不允许你使用shift倒退,如果你有他们没有使用tabindexes,没有他们从最后一个到第一个或第一个到最后。

要使[enter]键像[tab]键那样工作,但仍能正常使用文本区域并提交button,请使用以下代码。 另外,这个代码允许你使用shift键向后退,Tab键从前到后回到前面。

源代码: https : //github.com/mikbe/SaneEnterKey

CoffeeScript的

 mbsd_sane_enter_key = -> input_types = "input, select, button, textarea" $("body").on "keydown", input_types, (e) -> enter_key = 13 tab_key = 9 if e.keyCode in [tab_key, enter_key] self = $(this) # some controls should just press enter when pressing enter if e.keyCode == enter_key and (self.prop('type') in ["submit", "textarea"]) return true form = self.parents('form:eq(0)') # Sort by tab indexes if they exist tab_index = parseInt(self.attr('tabindex')) if tab_index input_array = form.find("[tabindex]").filter(':visible').sort((a,b) -> parseInt($(a).attr('tabindex')) - parseInt($(b).attr('tabindex')) ) else input_array = form.find(input_types).filter(':visible') # reverse the direction if using shift move_direction = if e.shiftKey then -1 else 1 new_index = input_array.index(this) + move_direction # wrap around the controls if new_index == input_array.length new_index = 0 else if new_index == -1 new_index = input_array.length - 1 move_to = input_array.eq(new_index) move_to.focus() move_to.select() false $(window).on 'ready page:load', -> mbsd_sane_enter_key() 

JavaScript的

 var mbsd_sane_enter_key = function() { var input_types; input_types = "input, select, button, textarea"; return $("body").on("keydown", input_types, function(e) { var enter_key, form, input_array, move_direction, move_to, new_index, self, tab_index, tab_key; enter_key = 13; tab_key = 9; if (e.keyCode === tab_key || e.keyCode === enter_key) { self = $(this); // some controls should react as designed when pressing enter if (e.keyCode === enter_key && (self.prop('type') === "submit" || self.prop('type') === "textarea")) { return true; } form = self.parents('form:eq(0)'); // Sort by tab indexes if they exist tab_index = parseInt(self.attr('tabindex')); if (tab_index) { input_array = form.find("[tabindex]").filter(':visible').sort(function(a, b) { return parseInt($(a).attr('tabindex')) - parseInt($(b).attr('tabindex')); }); } else { input_array = form.find(input_types).filter(':visible'); } // reverse the direction if using shift move_direction = e.shiftKey ? -1 : 1; new_index = input_array.index(this) + move_direction; // wrap around the controls if (new_index === input_array.length) { new_index = 0; } else if (new_index === -1) { new_index = input_array.length - 1; } move_to = input_array.eq(new_index); move_to.focus(); move_to.select(); return false; } }); }; $(window).on('ready page:load', function() { mbsd_sane_enter_key(); } 

改变这种行为实际上比原生实现的默认行为创造了更好的用户体验。 考虑到从用户的angular度来看,回车键的行为已经不一致,因为在单行input中,input往往会提交一个表单,而在多行文本区域中,它只是简单地将一个换行符添加到领域。

我最近这样做(使用jQuery):

 $('input.enterastab, select.enterastab, textarea.enterastab').live('keydown', function(e) { if (e.keyCode==13) { var focusable = $('input,a,select,button,textarea').filter(':visible'); focusable.eq(focusable.index(this)+1).focus(); return false; } }); 

这不是非常有效率,但工作得很好,是可靠的 – 只要将“enterastab”类添加到任何应该以这种方式运行的input元素。

我把OPs解决scheme重新编译为Knockout绑定,并认为我会分享它。 非常感谢 :-)

这是一个小提琴

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type="text/javascript"></script> <script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js" type="text/javascript"></script> </head> <body> <div data-bind="nextFieldOnEnter:true"> <input type="text" /> <input type="text" /> <select> <option value="volvo">Volvo</option> <option value="saab">Saab</option> <option value="mercedes">Mercedes</option> <option value="audi">Audi</option> </select> <input type="text" /> <input type="text" /> </div> <script type="text/javascript"> ko.bindingHandlers.nextFieldOnEnter = { init: function(element, valueAccessor, allBindingsAccessor) { $(element).on('keydown', 'input, select', function (e) { var self = $(this) , form = $(element) , focusable , next ; if (e.keyCode == 13) { focusable = form.find('input,a,select,button,textarea').filter(':visible'); var nextIndex = focusable.index(this) == focusable.length -1 ? 0 : focusable.index(this) + 1; next = focusable.eq(nextIndex); next.focus(); return false; } }); } }; ko.applyBindings({}); </script> </body> </html> 

我想出了最简单的香草JS代码片段:

 document.addEventListener('keydown', function (event) { if (event.keyCode === 13 && event.target.nodeName === 'INPUT') { var form = event.target.form; var index = Array.prototype.indexOf.call(form, event.target); form.elements[index + 1].focus(); event.preventDefault(); } }); 

适用于IE 9+和现代浏览器。

这里是一个angular.js指令,让enter使用其他答案作为灵感来到下一个领域。 这里有一些或许是奇怪的代码,因为我只使用jQlite打包的angular度。 我相信这里的大多数function都可以在所有浏览器中使用> IE8。

 angular.module('myapp', []) .directive('pdkNextInputOnEnter', function() { var includeTags = ['INPUT', 'SELECT']; function link(scope, element, attrs) { element.on('keydown', function (e) { // Go to next form element on enter and only for included tags if (e.keyCode == 13 && includeTags.indexOf(e.target.tagName) != -1) { // Find all form elements that can receive focus var focusable = element[0].querySelectorAll('input,select,button,textarea'); // Get the index of the currently focused element var currentIndex = Array.prototype.indexOf.call(focusable, e.target) // Find the next items in the list var nextIndex = currentIndex == focusable.length - 1 ? 0 : currentIndex + 1; // Focus the next element if(nextIndex >= 0 && nextIndex < focusable.length) focusable[nextIndex].focus(); return false; } }); } return { restrict: 'A', link: link }; }); 

以下是我在应用程序中使用它的方法,只需在pdk-next-input-on-enter上添加pdk-next-input-on-enter指令即可。 我正在使用条形码扫描器将数据input到字段中,扫描器的默认function是模拟keayboard,input扫描的条形码数据后input一个确认键。

这个代码有一个副作用(对于我的用例是正面的),如果它将焦点移动到一个button上,那么回车键事件将导致button的操作被激活。 这对我的stream程非常有效,因为我的标记中的最后一个表单元素是一个button,一旦所有的字段已经通过扫描条形码“标签”,我想激活它。

 <!DOCTYPE html> <html ng-app=myapp> <head> <script src="angular.min.js"></script> <script src="controller.js"></script> </head> <body ng-controller="LabelPrintingController"> <div class='.container' pdk-next-input-on-enter> <select ng-options="p for p in partNumbers" ng-model="selectedPart" ng-change="selectedPartChanged()"></select> <h2>{{labelDocument.SerialNumber}}</h2> <div ng-show="labelDocument.ComponentSerials"> <b>Component Serials</b> <ul> <li ng-repeat="serial in labelDocument.ComponentSerials"> {{serial.name}}<br/> <input type="text" ng-model="serial.value" /> </li> </ul> </div> <button ng-click="printLabel()">Print</button> </div> </body> </html> 

我遇到过类似的问题,我想在数字键盘上按+键select下一个字段。 现在我已经发布了一个我认为会帮助你的图书馆。

PlusAsTab :一个jQuery插件,使用数字键encryption键作为标签键的等价物。

既然你想input / ,你可以设置选项。 找出你想用哪个键与jQuery event.which演示 。

 JoelPurra.PlusAsTab.setOptions({ // Use enter instead of plus // Number 13 found through demo at // https://api.jquery.com/event.which/ key: 13 }); // Matches all inputs with name "a[]" (needs some character escaping) $('input[name=a\\[\\]]').plusAsTab(); 

您可以在PlusAsTabinput标签演示中自行尝试。

我只用JavaScript工作。 Firefox不会让你更新keyCode,所以你可以做的只是捕获keyCode 13,并强制它通过tabIndex关注下一个元素,就像keyCode 9被按下一样。 棘手的部分是find下一个tabIndex。 我已经testing了这只在IE8-IE10和Firefox,它的工作原理:

 function ModifyEnterKeyPressAsTab(event) { var caller; var key; if (window.event) { caller = window.event.srcElement; //Get the event caller in IE. key = window.event.keyCode; //Get the keycode in IE. } else { caller = event.target; //Get the event caller in Firefox. key = event.which; //Get the keycode in Firefox. } if (key == 13) //Enter key was pressed. { cTab = caller.tabIndex; //caller tabIndex. maxTab = 0; //highest tabIndex (start at 0 to change) minTab = cTab; //lowest tabIndex (this may change, but start at caller) allById = document.getElementsByTagName("input"); //Get input elements. allByIndex = []; //Storage for elements by index. c = 0; //index of the caller in allByIndex (start at 0 to change) i = 0; //generic indexer for allByIndex; for (id in allById) //Loop through all the input elements by id. { allByIndex[i] = allById[id]; //Set allByIndex. tab = allByIndex[i].tabIndex; if (caller == allByIndex[i]) c = i; //Get the index of the caller. if (tab > maxTab) maxTab = tab; //Get the highest tabIndex on the page. if (tab < minTab && tab >= 0) minTab = tab; //Get the lowest positive tabIndex on the page. i++; } //Loop through tab indexes from caller to highest. for (tab = cTab; tab <= maxTab; tab++) { //Look for this tabIndex from the caller to the end of page. for (i = c + 1; i < allByIndex.length; i++) { if (allByIndex[i].tabIndex == tab) { allByIndex[i].focus(); //Move to that element and stop. return; } } //Look for the next tabIndex from the start of page to the caller. for (i = 0; i < c; i++) { if (allByIndex[i].tabIndex == tab + 1) { allByIndex[i].focus(); //Move to that element and stop. return; } } //Continue searching from the caller for the next tabIndex. } //The caller was the last element with the highest tabIndex, //so find the first element with the lowest tabIndex. for (i = 0; i < allByIndex.length; i++) { if (allByIndex[i].tabIndex == minTab) { allByIndex[i].focus(); //Move to that element and stop. return; } } } } 

要使用此代码,请将其添加到您的htmlinput标记中:

 <input id="SomeID" onkeydown="ModifyEnterKeyPressAsTab(event);" ... > 

或者将它添加到javascript中的元素:

 document.getElementById("SomeID").onKeyDown = ModifyEnterKeyPressAsTab; 

其他一些说明:

我只需要它来处理我的input元素,但如果需要的话,可以将其扩展到其他文档元素。 为此,getElementsByClassName是非常有用的,但这是一个完整的其他话题。

限制是它只在你添加到你的allById数组的元素之间选项卡。 它没有select你浏览器的其他function,比如HTML文档之外的工具栏和菜单。 也许这是一个function,而不是一个限制。 如果你喜欢,陷阱keyCode 9,这种行为也可以使用Tab键。

您可以使用我的代码,在Mozilla,IE和Chrome中testing

  // Use to act like tab using enter key $.fn.enterkeytab=function(){ $(this).on('keydown', 'input, select,', function(e) { var self = $(this) , form = self.parents('form:eq(0)') , focusable , next ; if (e.keyCode == 13) { focusable = form.find('input,a,select,button').filter(':visible'); next = focusable.eq(focusable.index(this)+1); if (next.length) { next.focus(); } else { alert("wd"); //form.submit(); } return false; } }); } 

如何使用?

$( “#forms”)enterkeytab()。 //input关键标签

如果可以的话,我会重新考虑这样做:在表单提交表单时按<Enter>的默认操作,任何改变默认操作/预期行为的操作都可能导致网站的一些可用性问题。

支持Shift + Enter的Vanilla js,并可以select哪些HTML标签是可调焦的。 应该工作IE9 +。

  onKeyUp(e) { switch (e.keyCode) { case 13: //Enter var focusableElements = document.querySelectorAll('input, button') var index = Array.prototype.indexOf.call(focusableElements, document.activeElement) if(e.shiftKey) focus(focusableElements, index - 1) else focus(focusableElements, index + 1) e.preventDefault() break; } function focus(elements, index) { if(elements[index]) elements[index].focus() } } 

尝试这个…

 $(document).ready(function () { $.fn.enterkeytab = function () { $(this).on('keydown', 'input,select,text,button', function (e) { var self = $(this) , form = self.parents('form:eq(0)') , focusable , next ; if (e.keyCode == 13) { focusable = form.find('input,a,select').filter(':visible'); next = focusable.eq(focusable.index(this) + 1); if (next.length) { //if disable try get next 10 fields if (next.is(":disabled")){ for(i=2;i<10;i++){ next = focusable.eq(focusable.index(this) + i); if (!next.is(":disabled")) break; } } next.focus(); } return false; } }); } $("form").enterkeytab(); }); 

我有一个相似的需求。 这是我做的:

  <script type="text/javascript" language="javascript"> function convertEnterToTab() { if(event.keyCode==13) { event.keyCode = 9; } } document.onkeydown = convertEnterToTab; </script> 

在所有这些情况下,只能在Chrome和IE中使用,我添加了下面的代码来解决这个问题:

var key =(window.event)? e.keyCode:e.which;

如果keycode等于13,我testing了关键值

  $('body').on('keydown', 'input, select, textarea', function (e) { var self = $(this) , form = self.parents('form:eq(0)') , focusable , next ; var key = (window.event) ? e.keyCode : e.which; if (key == 13) { focusable = form.find('input,a,select,button,textarea').filter(':visible'); next = focusable.eq(focusable.index(this) + 1); if (next.length) { next.focus(); } else { focusable.click(); } return false; } });