Warum werden Formulare mit einem einzelnen Eingabefeld beim Drücken der Eingabetaste gesendet?


77

Warum lädt a <form>mit einem einzelnen <input>Feld das Formular neu, wenn der Benutzer einen Wert eingibt und die Taste drückt Enter, und dies nicht, wenn das Feld zwei oder mehr Felder enthält <form>?

Ich habe eine einfache Seite geschrieben , um diese Kuriosität zu testen.

Wenn Sie im zweiten Formular einen Wert eingeben und die Eingabetaste drücken, wird die Seite, die den eingegebenen Wert übergibt, neu geladen, als hätten Sie aufgerufen GET. Warum? und wie vermeide ich das?

<!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>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>testFormEnter</title>
</head>
<body>
<form>
  <input type="text" name="partid2" id="partid2" />
  <input type="text" name="partdesc" id="partdesc"  />
</form>
  <p>2 field form works fine</p>
<form>
<input type="text" name="partid" id="partid"  />
</form>
<p>One field form reloads page when you press the Enter key why</p>
</body>
</html>

Antworten:


52

Dies ist ein wenig bekannter "Quirk", der schon eine Weile nicht mehr da ist. Ich weiß, dass einige Leute es auf verschiedene Weise gelöst haben.

Der einfachste Bypass ist meiner Meinung nach, einfach eine zweite Eingabe zu haben, die dem Benutzer nicht angezeigt wird. Zugegeben, nicht allzu benutzerfreundlich im Backend, es funktioniert, um das Problem zu beheben.

Ich sollte beachten, dass der häufigste Ort, an dem ich von diesem Problem höre, speziell mit dem Internet Explorer und nicht mit FireFox oder anderen ist. Obwohl es sie auch zu beeinflussen scheint.


2
Danke, ich wünschte, es wäre irgendwo dokumentiert. Ich habe Stunden damit verbracht, eine große Seite zu debuggen, weil ich dachte, es sei etwas anderes, das an meinen Ajax gebunden ist. Ich habe die "Eigenart" erst entdeckt, nachdem ich den Code extrahiert und Zeile für Zeile gelöscht habe. Was für eine Zeitverschwendung!
SD für den

2
Und Sie haben Recht, es ist eine einfache Lösung mit einem versteckten Feld. Übrigens, wenn Firefox betroffen ist 3.5.2. Vielleicht wird es als Feature angesehen.
SD für den

Ah ja, ich fühle deinen Schmerz ... so habe ich es vor 5-6 Jahren herausgefunden ...
Mitchel Sellers

2
Außerdem habe ich festgestellt, dass ein verstecktes Feld nicht immer funktioniert. Auf einer Seite war es so und auf einer anderen nicht - auch seltsam. Aber das Feld mit Javascript zu verstecken, hat den Trick getan. Sie müssen einen Artikel schreiben "Dinge, die Sie nicht wissen, die Ihre Zeit
verschlingen werden

3
Ich debugge in Chrome und das versteckte Feld scheint nicht zu funktionieren.
Chris

49

Dies ist ein bekannter Fehler in IE6 / 7/8 . Es scheint nicht, dass Sie eine Lösung dafür bekommen.

Die beste Problemumgehung, die Sie dafür tun können, besteht darin, ein weiteres verstecktes Feld hinzuzufügen (sofern Ihr technisches Gewissen dies zulässt). Der IE sendet ein Formular nicht mehr automatisch, wenn er feststellt, dass das Formular zwei Eingabefelder enthält.

Aktualisieren

Falls Sie sich gefragt haben, warum dies der Fall ist, stammt dieses Juwel direkt aus der HTML 2.0-Spezifikation (Abschnitt 8.2) :

Wenn ein Formular nur ein einzeiliges Texteingabefeld enthält, sollte der Benutzeragent die Eingabe in dieses Feld als Anforderung zum Senden des Formulars akzeptieren.


1
Dies geschieht auch in Firefox 3.5
cssmaniac

1
Verbrachte Stunden damit, dies in Chrome zu debuggen. Vielen Dank für den Hinweis, dass es von spec kam.
JM Yang

In dem Moment, in dem Sie als berechtigter Entwickler "by-design, RTFM" von w3org sind, weil Sie das Dokument nicht sorgfältig gelesen haben.
Nathan

Wenn dies ein Fehler war, dann nur, weil der IE lange nach dem Verfallsdatum an der Implementierung von HTML 2 festhielt. Der Abschnitt, den Sie gefunden haben, war zu dem Zeitpunkt, als Sie Ihre Antwort geschrieben haben, bereits lange veraltet: HTML 2.0 wurde 1995 veröffentlicht und 1997 durch HTML 3.2 ersetzt. Dieser Standard diktierte, wie Browser mit dem Senden von Formularen umgehen sollen . In HTML 4.0 (1999) wird lediglich über das Aktivieren einer Senden-Schaltfläche anhand eines Beispiels zum Senden eines Formulars gesprochen ( z. B. ==).
Martijn Pieters

1
Schließlich fügte HTML 5, das 2012 veröffentlicht wurde (also 3 Jahre nach Ihrer Antwort), den Begriff der impliziten Formularübermittlung hinzu und kodifizierte, was Browser die ganze Zeit getan haben: Senden des Formulars, wenn ein Benutzer die Eingabetaste in einem einzeiligen Textfeld drückt.
Martijn Pieters

8

Nein, das Standardverhalten ist, dass bei der Eingabe die letzte Eingabe im Formular gesendet wird. Wenn Sie überhaupt nicht einreichen möchten, können Sie hinzufügen:

<form onsubmit="return false;">

Oder in Ihrer Eingabe

<input ... onkeypress="return event.keyCode != 13;">

Natürlich gibt es schönere Lösungen, aber diese sind ohne Bibliothek oder Framework einfacher.


Ich bin gerade auf dieses Problem für meine Websites gestoßen. Es scheint mir, dass die neueste Chrome-Version jetzt W # SEC8.2 implementiert, wodurch einige Funktionen auf Websites, die ich entwickle, beeinträchtigt wurden .
David

7

Das Drücken der Eingabetaste funktioniert unterschiedlich, je nachdem, (a) wie viele Felder vorhanden sind und (b) wie viele Senden-Schaltflächen vorhanden sind. Es kann nichts tun, es kann das Formular ohne "erfolgreiche" Senden-Schaltfläche senden oder es kann so tun, als ob die erste Senden-Schaltfläche angeklickt wurde (sogar einen Klick dafür generieren!) Und mit dem Wert dieser Schaltfläche senden.

Wenn Sie beispielsweise input type="submit"Ihrem Formular mit zwei Feldern ein Formular hinzufügen , werden Sie feststellen, dass es auch gesendet wird.

Dies ist eine uralte Browser-Eigenart, die mindestens bis zum frühen Netscape (vielleicht weiter) zurückreicht und wahrscheinlich jetzt nicht geändert wird.

<form>

Ungültig ohne 'Aktion'. Wenn Sie nicht beabsichtigen, irgendwo etwas zu senden, und Sie keine Gruppierung von Optionsfeldnamen benötigen, können Sie das Formularelement einfach ganz weglassen.


Danke, gute Antwort. Obwohl ich das Formular brauche, um die Felder für Ajax zu serialisieren. Ich könnte es manuell codieren, aber bei vielen Formularen wäre es ein Schmerz.
SD für den

7

Hier ist der Code, mit dem ich das Problem gelöst habe:

<form>
<input type="text" name="partid" id="partid"  />
<input type="text" name="StackOverflow1370021" value="Fix IE bug" style="{display:none}" />
</form>

3

Es wird nicht die Seite als solche neu geladen, sondern das Formular gesendet.

In diesem Beispiel jedoch, weil Sie kein Aktionsattribut für das Formular haben, das es an sich selbst sendet, was den Eindruck erweckt, die Seite neu zu laden.

Außerdem kann ich das von Ihnen beschriebene Verhalten nicht wiederholen. Wenn ich in einer Texteingabe in einem Formular bin und die Eingabetaste drücke, wird das Formular gesendet, unabhängig davon, wo sich die Eingabe im Formular befindet oder wie viele Eingaben es gibt.

Vielleicht möchten Sie dies in verschiedenen Browsern ausprobieren.


Du hast recht, ich habe nicht die richtigen Worte verwendet. Es sendet das Formular und da ich keine Aktion spezifiziere, ist es standardmäßig auf sich selbst eingestellt. Ich habe das genaue HTML kopiert und es in IE8 und Firefox 3.5.2 ausgeführt. Ein Eingabeschlüssel in den ersten beiden Feldern, die sich im ersten Formular befinden, sendet das Formular nicht, während ein Eingabetaste im dritten Feld dies tut.
SD für den

2

Wie bereits erwähnt, basiert dies auf der HTML 2.0-Spezifikation:

So verhindern Sie dies, ohne Ihre URLs zu vermasseln:

<form>
    <input type="text" name="partid" id="partid"  />
    <input type="text" style="display: none;" />
</form>

1

Vielen Dank an alle, die geantwortet haben. Es ist ein Augenöffner, dass ein Formular mit einem einzelnen Feld anders funktioniert als ein Formular mit vielen Feldern.

Eine andere Möglichkeit, mit dieser automatischen Übermittlung umzugehen, besteht darin, eine Übermittlungsfunktion zu codieren, die false zurückgibt.

In meinem Fall hatte ich eine Schaltfläche mit einem Onclick-Ereignis, daher habe ich den Funktionsaufruf mit dem hinzugefügten returnSchlüsselwort in das Onsubmit-Ereignis verschoben. Wenn die aufgerufene Funktion false zurückgibt, erfolgt die Übermittlung nicht.

<form onsubmit="return ajaxMagic()">
<input type="text" name="partid" id="partid"  />
<input type="submit" value="Find Part" />
</form

function ajaxMagic() {
  ...
  return (false);
}

1

Die Lösung, die ich für alle von mir getesteten Browser (IE, FF, Chrome, Safari, Opera) gefunden habe, besteht darin, dass das erste Eingabeelement type=submitim Formular sichtbar und das erste Element im Formular sein muss. Ich konnte die CSS-Platzierung verwenden, um die Senden-Schaltfläche an den unteren Rand der Seite zu verschieben, und dies hatte keinen Einfluss auf die Ergebnisse!

<form id="form" action="/">
<input type="submit" value="ensures-the-enter-key-submits-the-form"
                      style="width:1px;height:1px;position:fixed;bottom:1px;"/>
<div id="header" class="header"></div>
<div id="feedbackMessages" class="feedbackPanel"></div>
     ...... lots of other input tags, etc...
</form>

0

Dieses Problem tritt sowohl im Internet Explorer als auch in Chrome auf. Es tritt in Firefox nicht auf. Eine einfache Lösung wäre, dem Formular-Tag das folgende Attribut hinzuzufügen: onsubmit = "return false"

Dies setzt natürlich voraus, dass Sie das Formular mit einem XMLHttpRequest-Objekt senden.


0

Ja, Formular mit einem einzelnen inputText-Feld, das in HTML 4
anders funktioniert. OnSubmit return false funktioniert bei mir nicht, aber der folgende Fehler funktioniert einwandfrei

<!--Fix  IE6/7/8 and  HTML 4 bug -->
    <input style="display:none;" type="text" name="StackOverflow1370021" value="Fix IE bug" />

0

Ich habe dies mit dem folgenden Code behandelt, bin mir aber nicht sicher, ob dies ein guter Ansatz ist. Durch Suchen nach Eingabefeldern in einem bestimmten Formular und wenn es 1 ist, verhindern Sie die Standardaktion.

 if($j("form#your-form input[type='text']").length == 1) {
   $j(this).bind("keypress", function(event) {
     if(event.which == 13) {
       event.preventDefault();
     }
   });
 }

-1

Ich denke, das ist eine Funktion, die ich aber auch deaktiviert habe. Es ist nicht sehr aufwendig, es zu deaktivieren. Erfassen Sie einfach die Eingabetaste, ignorieren Sie sie.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.