Ich möchte ein Formular erstellen, bei dem durch Drücken der Eingabetaste der Fokus auf das "nächste" Formularelement auf der Seite gerichtet wird. Die Lösung, die ich im Web immer wieder finde, ist ...
<body onkeydown="if(event.keyCode==13){event.keyCode=9; return event.keyCode}">
Leider scheint das nur im IE zu funktionieren. Das eigentliche Problem dieser Frage ist also, ob jemand eine Lösung kennt, die für FF und Chrome funktioniert. Außerdem möchte ich den Formularelementen lieber keine Onkeydown- Ereignisse hinzufügen , aber wenn dies der einzige Weg ist, muss dies der Fall sein.
Dieses Problem ähnelt der Frage 905222 , verdient aber meiner Meinung nach eine eigene Frage.
Bearbeiten: Außerdem habe ich gesehen, dass Leute das Problem angesprochen haben, dass dies kein guter Stil ist, da er vom Formularverhalten abweicht, an das Benutzer gewöhnt sind. Genau! Es ist eine Kundenanfrage :(
textarea
in der ersten Zeile aus dem Selektor zu entfernen . In einem Textbereich möchten Sie mit der Eingabetaste eine neue Zeile beginnen können.readonly
und zu ignorierendisabled
:filter(':visible:not([readonly]):enabled')
Ordnen Sie die [Eingabetaste] so zu, dass sie wie die [Tab] -Taste funktioniert
Ich habe die Antwort von Andre Van Zuydam , die bei mir nicht funktioniert hat, in jQuery umgeschrieben . Dies erfasst sowohl Enterals auch Shift+ Enter. EnterTabs vorwärts und Shift+ EnterTabs zurück.
Ich habe auch umgeschrieben, wie der Weg
self
durch das aktuelle Element im Fokus initialisiert wird. Auf diese Weise wird auch das Formular ausgewählt. Hier ist der Code:// 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() } });
Der Grund
textarea
ist enthalten, weil wir " tun " wollen, um darauf zuzugreifen. Außerdem möchten wir nicht verhindern, dass das Standardverhalten von Entereine neue Zeile einfügt.
Der Grund
a
undbutton
Die Standardaktion " und " konzentrieren sich weiterhin auf das nächste Element, da sie nicht immer eine andere Seite laden. Es kann einen Auslöser / Effekt auf solche wie ein Akkordeon oder einen Inhalt mit Registerkarten geben. Sobald Sie das Standardverhalten ausgelöst haben und die Seite ihren Spezialeffekt ausführt, möchten Sie dennoch zum nächsten Element wechseln, da Ihr Auslöser es möglicherweise gut eingeführt hat.
quelle
if (e.shiftKey) { enterKey() } else { enterKey() }
? Scheint so, als sollte es einfach sein :enterKey()
.Das einfachste Vanille-JS-Snippet, das ich mir ausgedacht habe:
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(); } });
Funktioniert in IE 9+ und modernen Browsern.
quelle
Uncaught TypeError: Array.prototype.indexOf called on null or undefined
Das hat bei mir funktioniert:
$(document).on('keydown', ':tabbable', function(e) { if (e.key === "Enter") { e.preventDefault(); var $canfocus = $(':tabbable:visible'); var index = $canfocus.index(document.activeElement) + 1; if (index >= $canfocus.length) index = 0; $canfocus.eq(index).focus(); } });
quelle
Danke für das gute Drehbuch.
Ich habe gerade das Verschiebungsereignis für die obige Funktion hinzugefügt, um zwischen Elementen zurückzukehren. Ich dachte, jemand könnte dies benötigen.
$('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; } });
quelle
e.keyCode
unde.which
sind veraltet. Sie sollten verwendene.key === "Enter"
. siehe developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCodeEs gibt Probleme mit allen hier angegebenen Implementierungen. Einige funktionieren nicht richtig mit Textbereichen und Übermittlungsschaltflächen, die meisten erlauben es Ihnen nicht, die Umschalttaste zu verwenden, um rückwärts zu gehen, keiner von ihnen verwendet Tabindexe, wenn Sie sie haben, und keiner von ihnen wickelt sich vom letzten zum ersten oder dem ersten um bis zum letzten.
Verwenden Sie den folgenden Code, damit sich die [Eingabetaste] wie die [Tab] -Taste verhält, aber dennoch ordnungsgemäß mit Textbereichen und Senden-Schaltflächen funktioniert. Darüber hinaus können Sie mit diesem Code die Umschalttaste verwenden, um rückwärts zu gehen, und das Tabbing wird von vorne nach hinten und von hinten nach vorne gewickelt.
Quellcode: 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(); }
quelle
Das Ändern dieses Verhaltens führt tatsächlich zu einer weitaus besseren Benutzererfahrung als das nativ implementierte Standardverhalten. Beachten Sie, dass das Verhalten der Eingabetaste aus Sicht des Benutzers bereits inkonsistent ist, da bei einer Eingabe in einer einzelnen Zeile die Eingabe dazu neigt, ein Formular zu senden, während in einem mehrzeiligen Textbereich einfach eine neue Zeile zum Inhalt der hinzugefügt wird Feld.
Ich habe es kürzlich so gemacht (verwendet 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; } });
Dies ist nicht besonders effizient, funktioniert aber gut genug und ist zuverlässig. Fügen Sie einfach die Klasse 'enterastab' zu jedem Eingabeelement hinzu, das sich auf diese Weise verhalten soll.
quelle
Ich überarbeitete die OPs-Lösung zu einer Knockout-Bindung und dachte, ich würde sie teilen. Vielen Dank :-)
Hier ist eine Geige
<!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>
quelle
Hier ist eine angle.js-Direktive, mit der enter zum nächsten Feld wechseln kann, wobei die anderen Antworten als Inspiration dienen. Es gibt hier vielleicht etwas seltsam aussehenden Code, weil ich nur das mit eckig verpackte jQlite verwende. Ich glaube, die meisten Funktionen hier funktionieren in allen Browsern> 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 }; });
So verwende ich es in der App, an der ich arbeite, indem ich einfach die
pdk-next-input-on-enter
Direktive zu einem Element hinzufüge . Ich verwende einen Barcode-Scanner, um Daten in Felder einzugeben. Die Standardfunktion des Scanners besteht darin, ein Keayboard zu emulieren und nach Eingabe der Daten des gescannten Barcodes eine Eingabetaste einzugeben.Dieser Code hat einen Nebeneffekt (einen positiven für meinen Anwendungsfall). Wenn der Fokus auf eine Schaltfläche verschoben wird, wird durch die Eingabe der Eingabetaste die Aktion der Schaltfläche aktiviert. Dies hat für meinen Flow sehr gut funktioniert, da das letzte Formularelement in meinem Markup eine Schaltfläche ist, die aktiviert werden soll, sobald alle Felder durch Scannen von Barcodes "tabbediert" wurden.
<!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>
quelle
Ich hatte ein ähnliches Problem, bei dem ich +auf den Nummernblock drücken wollte, um zum nächsten Feld zu gelangen. Jetzt habe ich eine Bibliothek veröffentlicht, von der ich denke, dass sie Ihnen helfen wird.
Da willst du enter / ↵stattdessen , können Sie die Optionen festlegen. Finden Sie heraus, welchen Schlüssel Sie für das jQuery-Ereignis verwenden möchten .
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();
Sie können es selbst in der PlusAsTab-Eingabe als Tab-Demo ausprobieren .
quelle
data-plus-as-tab="true"
, müssen Sie nichts tun, sonst können Sie es ausführen$("#new-input").plusAsTab()
. Schauen Sie sich dynamische Elemente und eine Beispielimplementierung in dieser Demo zur Verbesserung der Benutzererfahrung in HTML-Formularen an .Ich habe es nur in JavaScript funktionieren. In Firefox können Sie den keyCode nicht aktualisieren. Sie können also nur keyCode 13 abfangen und ihn zwingen, sich mit tabIndex auf das nächste Element zu konzentrieren, als ob keyCode 9 gedrückt wurde. Der schwierige Teil ist das Finden des nächsten tabIndex. Ich habe dies nur auf IE8-IE10 und Firefox getestet und es funktioniert:
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; } } } }
Um diesen Code zu verwenden, fügen Sie ihn Ihrem HTML-Eingabe-Tag hinzu:
<input id="SomeID" onkeydown="ModifyEnterKeyPressAsTab(event);" ... >
Oder fügen Sie es einem Element in Javascript hinzu:
document.getElementById("SomeID").onKeyDown = ModifyEnterKeyPressAsTab;
Ein paar andere Anmerkungen:
Ich brauchte es nur, um an meinen Eingabeelementen zu arbeiten, aber Sie können es bei Bedarf auch auf andere Dokumentelemente erweitern. Dafür ist getElementsByClassName sehr hilfreich, aber das ist ein ganz anderes Thema.
Eine Einschränkung besteht darin, dass nur Registerkarten zwischen den Elementen angezeigt werden, die Sie Ihrem allById-Array hinzugefügt haben. Es werden keine anderen Dinge angezeigt, die Ihr Browser möglicherweise verwendet, z. B. Symbolleisten und Menüs außerhalb Ihres HTML-Dokuments. Vielleicht ist dies eine Funktion anstelle einer Einschränkung. Wenn Sie möchten, fangen Sie keyCode 9 ab, und dieses Verhalten funktioniert auch mit der Tabulatortaste.
quelle
// 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; } }); }
Wie benutzt man?
quelle
Wenn Sie können, würde ich dies noch einmal überdenken: Die Standardaktion zum Drücken
<Enter>
in einem Formular sendet das Formular, und alles, was Sie tun, um diese Standardaktion / das erwartete Verhalten zu ändern, kann einige Usability-Probleme mit der Site verursachen.quelle
Vanilla js mit Unterstützung für Shift + Enter und der Möglichkeit zu wählen, welche HTML-Tags fokussierbar sind. Sollte IE9 + funktionieren.
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() } }
quelle
Versuche dies...
$(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(); });
quelle
Folgendes habe ich mir ausgedacht.
form.addEventListener("submit", (e) => { //On Submit let key = e.charCode || e.keyCode || 0 //get the key code if (key = 13) { //If enter key e.preventDefault() const inputs = Array.from(document.querySelectorAll("form input")) //Get array of inputs let nextInput = inputs[inputs.indexOf(document.activeElement) + 1] //get index of input after the current input nextInput.focus() //focus new input } }
quelle
Viele Antworten hier verwenden
e.keyCode
unde.which
die sind veraltet.Stattdessen sollten Sie verwenden
e.key === 'Enter'
.Dokumentation: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
Mit HTML:
<body onkeypress="if(event.key==='Enter' && event.target.form){focusNextElement(event); return false;}">
Mit jQuery:
$(window).on('keypress', function (ev) { if (ev.key === "Enter" && ev.currentTarget.form) focusNextElement(ev) }
Und mit Vanilla JS:
document.addEventListener('keypress', function (ev) { if (ev.key === "Enter" && ev.currentTarget.form) focusNextElement(ev); });
Sie können die
focusNextElement()
Funktion von hier aus übernehmen: https://stackoverflow.com/a/35173443/3356679quelle
Der einfachste Weg, um dieses Problem mit der Fokusfunktion von JavaScript wie folgt zu lösen:
Sie können es kopieren und @ home ausprobieren!
<!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title></title> </head> <body> <input id="input1" type="text" onkeypress="pressEnter()" /> <input id="input2" type="text" onkeypress="pressEnter2()" /> <input id="input3" type="text"/> <script type="text/javascript"> function pressEnter() { // Key Code for ENTER = 13 if ((event.keyCode == 13)) { document.getElementById("input2").focus({preventScroll:false}); } } function pressEnter2() { if ((event.keyCode == 13)) { document.getElementById("input3").focus({preventScroll:false}); } } </script> </body> </html>
quelle
Ich hatte ein ähnliches Bedürfnis. Folgendes habe ich getan:
<script type="text/javascript" language="javascript"> function convertEnterToTab() { if(event.keyCode==13) { event.keyCode = 9; } } document.onkeydown = convertEnterToTab; </script>
quelle
In all diesen Fällen funktioniert nur in Chrome und IE. Ich habe den folgenden Code hinzugefügt, um das zu lösen:
var key = (window.event)? e.keyCode: e.which;
und ich habe den Schlüsselwert getestet, wenn der Schlüsselcode gleich 13 ist
$('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; } });
quelle
$("#form input , select , textarea").keypress(function(e){ if(e.keyCode == 13){ var enter_position = $(this).index(); $("#form input , select , textarea").eq(enter_position+1).focus(); } });
quelle
Sie können die Formularelemente programmgesteuert iterieren und dabei den Onkeydown-Handler hinzufügen. Auf diese Weise können Sie den Code wiederverwenden.
quelle