Die Eingabetaste verhält sich wie ein Tab in Javascript

76

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

Ross
quelle

Antworten:

90

Ich habe die von Andrew vorgeschlagene Logik verwendet, die sehr effektiv ist. Und das ist meine Version:

$('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,a,select,button,textarea').filter(':visible');
        next = focusable.eq(focusable.index(this)+1);
        if (next.length) {
            next.focus();
        } else {
            form.submit();
        }
        return false;
    }
});

e.keycodeAbschreibungshinweis für den KeycodeEvent-Schlüsselcode (dh :): - https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

tcdona
quelle
28
Ich schlage vor, textareain der ersten Zeile aus dem Selektor zu entfernen . In einem Textbereich möchten Sie mit der Eingabetaste eine neue Zeile beginnen können.
Aimfeld
2
Ich schlage vor, Felder mit readonlyund zu ignorieren disabled:filter(':visible:not([readonly]):enabled')
SnakeDrak
Warum wird hier die Variable "self" verwendet?
Spikolynn
Ich weiß, dass dies ein sehr alter Thread ist, aber wie können wir mit diesem Code das Standardverhalten von <input type = "button" /> zulassen? Wie kann mit der Eingabetaste auf die Schaltfläche geklickt werden?
Vishal_Kotecha
17

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

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.

6ft Dan
quelle
4
Was ist der Zweck des letzten Bits : if (e.shiftKey) { enterKey() } else { enterKey() }? Scheint so, als sollte es einfach sein : enterKey().
AVProgrammer
2
@AVProgrammer Damit sich die Eingabetaste wie ein Tab verhält , muss umgekehrt vorgehen, wenn die Umschalttaste gedrückt gehalten wird. In der Zeile, nach der Sie gefragt haben, kann die Eingabetaste überprüft werden, während die Umschalttaste gedrückt wird.
6ft Dan
2
In beiden Fällen ist es nicht sinnvoll, nach e.shiftKey zu suchen und enterKey aufzurufen.
Jeppe Andreasen
@JeppeAndreasen Wenn Sie möchten, dass es sich wie ein Tab verhält, dann ja. Weil Umschalt + Tab in die umgekehrte Richtung geht.
6ft Dan
2
Sie führen dieselbe Aktion aus, unabhängig davon, ob die Umschalttaste gedrückt wird oder nicht. Die if-Anweisung ist also nicht notwendig, wie auch der Programmierer betont hat
Jeppe Andreasen
17

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.

Vitaly Kusnezow
quelle
2
Ich glaube, das sollte die richtige Antwort sein. Das OP hat nicht nach Abfragen gefragt, und dies ist viel einfacher und kompatibler.
Blaues Wasser
1
Ich bin mir nicht sicher, warum so viele dieser Antworten davon ausgehen, dass ein Formular vorhanden ist ... Dies funktioniert nicht:Uncaught TypeError: Array.prototype.indexOf called on null or undefined
Justin
12

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

});
Mayur Sarang
quelle
Das scheint nicht zu funktionieren . Der Geigenlink ist tot (und wurde entfernt).
Isherwood
Dies erfordert jquery-ui für den Tabellenselektor
Mat Mannion
11

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;
}
});
Andre Van Zuydam
quelle
Ich habe eine Gegenstimme abgegeben, weil mir der Code gefällt. Obwohl es beim Testen bei mir nicht funktioniert hat. Also habe ich eine funktionierende Antwort geschrieben: stackoverflow.com/a/27545387/1500195
6ft Dan
e.keyCodeund e.whichsind veraltet. Sie sollten verwenden e.key === "Enter". siehe developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
oriadam
6

Es 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();
}
Mike Bethany
quelle
4

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.

Andrew
quelle
1
Kurz und prägnant! Begann auch mit etwas Ähnlichem, aber jetzt habe ich es erweitert - siehe meine Antwort (auf dieser Seite) mit PlusAsTab .
Joel Purra
War speziell auf der Suche nach etwas zu stehlen, das unsichtbare Felder betrachtete. Die meisten anderen Lösungen, die ich gefunden habe, tun dies nicht. Danke
Simon_Weaver
4

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>
Damien Sawyer
quelle
Ihre Lösung ist genau das, wonach ich gesucht habe, mit einer Ausnahme: Ich möchte dieses Verhalten bei der Eingabe von Typschaltflächen nicht. Wie kann ich sie ausschließen? Ich habe es geschafft, die Schaltfläche als <button> -Element zu definieren, möchte sie aber als <input type = "button"> definieren können. Danke
bzamfir
1
Hallo. Versuchen Sie vielleicht, den Selektor wie folgt zu ändern? .... $ (Element) .on ('Keydown', 'Eingabe: nicht (Eingabe [Typ = Schaltfläche]), Auswahl', Funktion (e) {.....
Damien Sawyer
+1; Das ist großartig, ich benutze Knockout ziemlich oft, aber das Projekt, für das ich diese Funktionalität benötige, ist eine AngularJS-App. Wenn es Ihnen nichts ausmacht, leihe ich mir Ihren Impl-Code aus und poste eine Antwort mit einer benutzerdefinierten Direktive für Angular.
Joshperry
Alles süß. Benutzerdefinierte Bindungen sind fantastisch, wenn Sie Ihren Kopf um sie herum bekommen. :-)
Damien Sawyer
2

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-enterDirektive 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>
Joshperry
quelle
1

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.

PlusAsTab : Ein jQuery-Plugin zur Verwendung der Numpad-Plus-Taste als Tabulator-Schlüsseläquivalent.

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 .

Joel Purra
quelle
Das ist interessant. Aber ich habe eine Frage: Was passiert, wenn nach dem Laden der Seite weitere UI-Elemente hinzugefügt werden (z. B. bei Verwendung der Knockout-Bindung mit einem beobachtbaren Array)? Was muss getan werden, damit neu hinzugefügte Steuerelemente auch Eingabe als Registerkarte verarbeiten? Danke
bzamfir
@bzamfir: Wenn es sich in einem enthaltenden Element mit befindet 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 .
Joel Purra
0

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.

Jroonk
quelle
0

Sie können meinen Code unten verwenden, der in Mozilla, IE und Chrome getestet wurde

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

$ ("# form"). enterkeytab (); // Schlüsselregisterkarte eingeben

Francis Tudlong
quelle
0

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.

Ian Oxley
quelle
1
Normalerweise würde ich zustimmen, aber mit unserer App können Benutzer solche Dinge separat für ihre eigenen Konten festlegen, und der Kunde bietet Geld dafür an, sodass ich nicht glaube, dass wir es rechtfertigen können, uns zu behaupten.
Ross
Außer das Standardverhalten der Eingabetaste ist bereits inkonsistent. Es wird nur gesendet, wenn Sie sich innerhalb eines Texteingabetyps befinden. Die meisten anderen Eingabetypen haben ein eigenes definiertes Verhalten für die Eingabetaste. Solange er die Tabulatortaste nicht etwas anderem zuordnet, scheint dies eine weitaus bessere Lösung zu sein als das bizarre Verhalten von Anfang an.
Beep Beep
3
Ich habe festgestellt, dass das Drücken der Eingabetaste zum Senden NICHT erwartet wird und in der Tat sehr ärgerlich ist. Tatsächlich hat mich der Client auf jeder einzelnen Website, die ich jemals erstellt habe, gebeten, dieses Verhalten zu ändern, da es unerwünscht ist. Ich beschuldige jemanden [Husten] Microsoft [/ Husten], der nicht zugeben kann, dass er eine schlechte Wahl für dieses fortgesetzte Verhalten getroffen hat, angesichts der überwältigenden Beweise, dass es nicht erwünscht ist.
Mike Bethany
0

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()
    }
  }
jiv-e
quelle
0

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();
});
Lucio Pelinson
quelle
0

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
}
}
DynamisDevelopment
quelle
Willkommen bei Stack Overflow. Derzeit gibt es 19 weitere Antworten auf diese Frage. Wenn Sie damit rechnen, Upvotes für Ihre zu erhalten, sollten Sie erklären, warum dies besser ist als die anderen.
chb
0

Viele Antworten hier verwenden e.keyCodeund e.whichdie sind veraltet.

Stattdessen sollten Sie verwenden e.key === 'Enter'.

Dokumentation: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

  • Es tut mir leid, aber ich kann diese Schnipsel gerade nicht testen. Komme später nach dem Testen wieder.

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

Oriadam
quelle
0

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>
oezkanbu
quelle
-1

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>  
Bobby Ortiz
quelle
-1

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;
    }
});
Thiago Raphael Raheem Marinho
quelle
-1
$("#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();
    }
});
user11706828
quelle
Könnten Sie bitte eine kleine Erklärung des Codes geben, um die Antwort verständlicher zu machen?
Carles Sans Fuentes
Zuerst müssen Sie alle Eingabefelder im Formular auswählen und dann müssen Sie das Tastendruckereignis in alle Eingabefelder binden. Dann müssen Sie prüfen, ob Sie den Tastendruck eingeben oder nicht. Wenn Sie die Eingabetaste in einem Eingabefeld drücken, müssen Sie einen Index dafür erhalten Eingabefeld und Inkrement zum Index hinzufügen, um das nächste Eingabefeld zu finden. Wenn Sie das nächste Eingabefeld finden, müssen Sie sich darauf konzentrieren ....!
user11706828
-2

Sie können die Formularelemente programmgesteuert iterieren und dabei den Onkeydown-Handler hinzufügen. Auf diese Weise können Sie den Code wiederverwenden.

Byron Whitlock
quelle
Das habe ich letztendlich getan. Vielen Dank!
Ross