Wie erhalte ich Text eines Eingabetextfelds während onKeyPress?

85

Ich versuche, den Text in ein Textfeld zu bekommen, während der Benutzer ihn eingibt ( jsfiddle playground ):

function edValueKeyPress() {
    var edValue = document.getElementById("edValue");
    var s = edValue.value;

    var lblValue = document.getElementById("lblValue");
    lblValue.innerText = "The text box contains: " + s;

    //var s = $("#edValue").val();
    //$("#lblValue").text(s);    
}
<input id="edValue" type="text" onKeyPress="edValueKeyPress()"><br>
<span id="lblValue">The text box contains: </span>

Der Code wird fehlerfrei ausgeführt, mit der Ausnahme, dass der Wert der input textBox während onKeyPressimmer der Wert vor der Änderung ist:

Geben Sie hier die Bildbeschreibung ein

Frage : Wie erhalte ich währenddessen den Text eines Textfelds onKeyPress?

Bonus Chatter

Es gibt drei Ereignisse im Zusammenhang mit "Der Benutzer tippt" im HTML-DOM:

  • onKeyDown
  • onKeyPress
  • onKeyUp

In Windows wird die Reihenfolge der WM_KeyNachrichten wichtig, wenn der Benutzer eine Taste gedrückt hält und sich die Taste wiederholt:

  • WM_KEYDOWN('a')- Benutzer hat die ATaste gedrückt
  • WM_CHAR('a')- Ein aZeichen wurde vom Benutzer empfangen
  • WM_CHAR('a')- Ein aZeichen wurde vom Benutzer empfangen
  • WM_CHAR('a')- Ein aZeichen wurde vom Benutzer empfangen
  • WM_CHAR('a')- Ein aZeichen wurde vom Benutzer empfangen
  • WM_CHAR('a')- Ein aZeichen wurde vom Benutzer empfangen
  • WM_KEYUP('a')- Der Benutzer hat den ASchlüssel freigegeben

Es werden fünf Zeichen in einem Textsteuerelement angezeigt: aaaaa

Der wichtige Punkt ist, dass Sie auf die WM_CHARNachricht antworten , die sich wiederholt. Andernfalls verpassen Sie Ereignisse, wenn eine Taste gedrückt wird.

In HTML sieht es etwas anders aus:

  • onKeyDown
  • onKeyPress
  • onKeyDown
  • onKeyPress
  • onKeyDown
  • onKeyPress
  • onKeyDown
  • onKeyPress
  • onKeyDown
  • onKeyPress
  • onKeyUp

HTML liefert eine KeyDownund KeyPressjede Schlüsselwiederholung. Und das KeyUpEreignis wird nur ausgelöst, wenn der Benutzer den Schlüssel loslässt.

Nehmen Sie weg

  • Ich kann auf onKeyDownoder antworten onKeyPress, aber beide werden noch angehoben, bevor das input.valueaktualisiert wurde
  • Ich kann nicht antworten onKeyUp, da dies nicht geschieht, wenn sich der Text im Textfeld ändert.

Frage: Wie erhalte ich währenddessen den Text eines Textfelds onKeyPress?

Bonuslesung

Ian Boyd
quelle
1
Ich glaube, Sie müssen den aktuellen Tastendruck an den Wert anhängen, bevor Sie ihn zurückgeben. Der Wert wird bei keyUp aktualisiert, aber die Daten stehen Ihnen bei keyDown zur Verfügung.
Mathletics
Key Up funktioniert für mich, Sie brauchen kein jQ für so etwas, es sei denn, Sie möchten Bloat hinzufügen
Ryan B
es ist genug nur onKeyUp für Ihre Aufgabe
dmytro
@mit Nur die Behandlung onKeyUpzeigt die Änderungen im Textfeld nicht sofort an .
Ian Boyd
Wenn Sie eine Taste gedrückt halten und ein Ergebnis im Textfeld erhalten möchten, sollten Sie natürlich sowohl die Geige von onKeyPress als auch die Ereignisse von onKeyDown Jonathan M verwenden. Wenn Sie jedoch ein Ergebnis erzielen möchten, ohne die Tasten gedrückt zu halten, reicht dies nur für meine Geige aus .
Dmytro

Antworten:

18

Das Handling inputEreignis ist eine konsequente Lösung: Es wird unterstützt für textareaundinput Elemente in allen modernen Browsern und es feuert genau , wenn Sie es brauchen:

function edValueKeyPress() {
    var edValue = document.getElementById("edValue");
    var s = edValue.value;

    var lblValue = document.getElementById("lblValue");
    lblValue.innerText = "The text box contains: " + s;
}
<input id="edValue" type="text" onInput="edValueKeyPress()"><br>
<span id="lblValue">The text box contains: </span>

Ich würde das allerdings ein bisschen umschreiben:

function showCurrentValue(event)
{
    const value = event.target.value;
    document.getElementById("lblValue").innerText = value;
}
<input id="edValue" type="text" onInput="showCurrentValue(event)"><br>
The text box contains: <span id="lblValue"></span>

YakovL
quelle
54

Halte es einfach. Verwenden Sie beide onKeyPress()und onKeyUp():

<input id="edValue" type="text" onKeyPress="edValueKeyPress()" onKeyUp="edValueKeyPress()">

Dies sorgt dafür, dass der aktuellste Zeichenfolgenwert (nach dem Hochfahren des Schlüssels) abgerufen wird, und aktualisiert sich auch, wenn der Benutzer einen Schlüssel gedrückt hält.

jsfiddle: http://jsfiddle.net/VDd6C/8/

Jonathan M.
quelle
Da die Antwort von arnaud576875 aufgeben und zurückgreifen musste onKeyUp(um den Verwendungszweck zu vereiteln onKeypress), ist dies die einfachste, sauberste und am nächsten liegende Antwort, die jeder sehen wird. Nur der aufmerksamste Benutzer wird feststellen, dass das Feedback nicht mit dem übereinstimmt, was er eingegeben hat.
Ian Boyd
@ Ian, gerne helfen. Was meinst du mit "Feedback stimmt nicht mit dem überein, was sie eingegeben haben"? Ist eine Anpassung erforderlich?
Jonathan M
Ich erinnere mich, was ich jetzt meinte! Das Feedback, auf das ich mich beziehe, wäre, das <input>Element rot oder grün zu färben oder dem Benutzer ein anderes Feedback zu geben, dass das, was er eingegeben hat, gut oder schlecht ist. Während Ihre akzeptierte Antwort immer noch unter dem Problem leidet, immer "off-by-one" zu sein : Nur der aufmerksamste Benutzer wird bemerken, dass das Feedback nicht mit dem übereinstimmt, was er eingegeben hat. " In Wirklichkeit, da das off-by- Ein Fehler tritt nur während der Tastenwiederholung auf (dh sie halten die Taste gedrückt). Niemand (außer mir) wird das Problem bemerken.
Ian Boyd
19

Der Wert des Eingabetextfelds während onKeyPress ist immer der Wert vor der Änderung

Dies ist absichtlich so: Der Ereignis-Listener kann den Tastendruck abbrechen.

Wenn die Ereignis-Listener das Ereignis abbrechen , wird der Wert nicht aktualisiert. Wenn das Ereignis nicht abgebrochen wird, wird der Wert aktualisiert, jedoch nachdem der Ereignis-Listener aufgerufen wurde .

Um den Wert zu erhalten, nachdem der Feldwert aktualisiert wurde, planen Sie eine Funktion, die in der nächsten Ereignisschleife ausgeführt werden soll. Der übliche Weg, dies zu tun, besteht darin, setTimeoutmit einer Zeitüberschreitung von 0:

$('#field').keyup(function() {
    var $field = $(this);

    // this is the value before the keypress
    var beforeVal = $field.val();

    setTimeout(function() {

        // this is the value after the keypress
        var afterVal = $field.val();
    }, 0);
});

Versuchen Sie es hier: http://jsfiddle.net/Q57gY/2/

Bearbeiten : Einige Browser (z. B. Chrome) lösen keine Tastendruckereignisse für die Rücktaste aus. Tastendruck wurde geändert, um den Code einzugeben.

Arnaud Le Blanc
quelle
Wollte dies posten. Hier ist die jsFiddle, die ich gemacht habe.
Kapa
Sie haben Recht, Chrome scheint keine Tastendruckereignisse für die Rücktaste auszulösen. aktualisiert
Arnaud Le Blanc
@ Ian, möchte das OP, dass es aktualisiert wird, wenn ein Schlüssel gedrückt gehalten wird? War mir nicht sicher, ob dies eine Voraussetzung war. Diese Lösung verfügt jedoch nicht über diese Funktionalität.
Jonathan M
Um es klar auszudrücken: Das Nichtauslösen von Tastendruckereignissen für die Rücktaste erfolgt gemäß Standard: "Taste, die einen Zeichenwert erzeugt" - für andere Tasten verwenden Sie "Keydown" (vor Änderung, stornierbar) oder "Keyup" (nach Änderung)
Sebilasse
5

halte es kompakt.
Jedes Mal, wenn Sie eine Taste drücken, wird die Funktion edValueKeyPress()aufgerufen.
Sie haben auch einige Variablen in dieser Funktion deklariert und initialisiert. Dies verlangsamt den Prozess und erfordert mehr CPU und Speicher.
Sie können diesen Code einfach verwenden - abgeleitet von einer einfachen Ersetzung.

function edValueKeyPress()
{
    document.getElementById("lblValue").innerText =""+document.getElementById("edValue").value;
}

Das ist alles was du willst und es ist schneller!

Wajahath
quelle
3
<asp:TextBox ID="txtMobile" runat="server" CssClass="form-control" style="width:92%;  margin:0px 5px 0px 5px;" onkeypress="javascript:return isNumberKey(event);" MaxLength="12"></asp:TextBox>

<script>
    function isNumberKey(evt) {
        var charCode = (evt.which) ? evt.which : event.keyCode;
        if (charCode > 31 && (charCode < 48 || charCode > 57)) {
            return false;
        }
        return true;
    }
</script>
Raksh Kumpel
quelle
3

Keine der bisherigen Antworten bietet eine vollständige Lösung. Es gibt einige Probleme zu lösen:

  1. Nicht alle Tastendrücke werden an keydownund übergebenkeypress Handler (zB Backspace und Löschtasten unterdrückt werden von einigen Browsern).
  2. Handhabung keydown ist keine gute Idee. Es gibt Situationen, in denen ein Tastendruck NICHT zu einem Tastendruck führt!
  3. setTimeout() Stillösungen werden unter Google Chrome / Blink-Webbrowsern verzögert, bis der Benutzer aufhört zu tippen.
  4. Maus- und Berührungsereignisse können verwendet werden, um Aktionen wie Ausschneiden, Kopieren und Einfügen auszuführen. Diese Ereignisse lösen keine Tastaturereignisse aus.
  5. Abhängig von der Eingabemethode sendet der Browser möglicherweise keine Benachrichtigung, dass sich das Element geändert hat, bis der Benutzer vom Feld weg navigiert.

Eine richtige Lösung behandelt die keypress, keyup, inputundchange Veranstaltungen.

Beispiel:

<p><input id="editvalue" type="text"></p>
<p>The text box contains: <span id="labelvalue"></span></p>

<script>
function UpdateDisplay()
{
    var inputelem = document.getElementById("editvalue");
    var s = inputelem.value;

    var labelelem = document.getElementById("labelvalue");
    labelelem.innerText = s;
}

// Initial update.
UpdateDisplay();

// Register event handlers.
var inputelem = document.getElementById("editvalue");
inputelem.addEventListener('keypress', UpdateDisplay);
inputelem.addEventListener('keyup', UpdateDisplay);
inputelem.addEventListener('input', UpdateDisplay);
inputelem.addEventListener('change', UpdateDisplay);
</script>

Geige:

http://jsfiddle.net/VDd6C/2175/

Die Behandlung aller vier Ereignisse erfasst alle Randfälle. Bei der Arbeit mit Eingaben eines Benutzers sollten alle Arten von Eingabemethoden berücksichtigt und die browser- und geräteübergreifende Funktionalität überprüft werden. Der obige Code wurde in Firefox, Edge und Chrome auf dem Desktop sowie auf meinen Mobilgeräten getestet.

CubicleSoft
quelle
Warum nicht einfach inputEvent?
YakovL
inputfeuert nicht immer. Kein einzelnes Ereignis deckt alle Situationen ab.
CubicleSoft
wäre nett von dir, wenn du "nicht immer" ausführlicher beschreibst, wie du es keypressin der Antwort angegeben hast
YakovL
1

Normalerweise verkette ich den Wert des Feldes (dh bevor es aktualisiert wird) mit dem Schlüssel, der dem Schlüsselereignis zugeordnet ist. Im Folgenden wird aktuelles JS verwendet, sodass Anpassungen für die Unterstützung in älteren IE vorgenommen werden müssen.

Aktuelles JS-Beispiel

document.querySelector('#test').addEventListener('keypress', function(evt) {
    var real_val = this.value + String.fromCharCode(evt.which);
    if (evt.which == 8) real_val = real_val.substr(0, real_val.length - 2);
    alert(real_val);
}, false);

Unterstützung für ältere IEs Beispiel

//get field
var field = document.getElementById('test');

//bind, somehow
if (window.addEventListener)
    field.addEventListener('keypress', keypress_cb, false);
else
    field.attachEvent('onkeypress', keypress_cb);

//callback
function keypress_cb(evt) {
    evt = evt || window.event;
    var code = evt.which || evt.keyCode,
        real_val = this.value + String.fromCharCode(code);
    if (code == 8) real_val = real_val.substr(0, real_val.length - 2);
}

[BEARBEITEN - Dieser Ansatz deaktiviert standardmäßig das Drücken von Tasten für Dinge wie Rücktaste, STRG + A. Der obige Code passt zu ersteren, müsste aber weiter gebastelt werden, um letztere und einige andere Eventualitäten zu berücksichtigen. Siehe Ian Boyds Kommentar unten.]

Mitya
quelle
1
@ bažmegakapa Oder mit der deleteTaste oder wenn der Benutzer eine Taste drückt, die den Inhalt nicht ändert ( Ctrl+A), oder wenn der Benutzer Text auswählt und dann drückt a, um eine Teilmenge zu ersetzen. Es ist eine gute Idee, Utkanos, aber eine fragile.
Ian Boyd
1
Einverstanden. Ich werde es weglassen, da es einige Kilometer enthält, aber wie Sie sagen, müssten Sie diese Vorbehalte berücksichtigen.
Mitya
1

einfach...

Schreiben Sie in Ihren keyPress-Ereignishandler

void ValidateKeyPressHandler(object sender, KeyPressEventArgs e)
{
    var tb = sender as TextBox;
    var startPos = tb.SelectionStart;
    var selLen= tb.SelectionLength;

    var afterEditValue = tb.Text.Remove(startPos, selLen)
                .Insert(startPos, e.KeyChar.ToString()); 
    //  ... more here
}
Charles Bretana
quelle
Was passiert, wenn e.KeyCharder BackspaceSchlüssel ist? Oder der DeleteSchlüssel? Oder Ctrl+A?
Ian Boyd
Ist das überhaupt JavaScript? void? object? Methoden in Großbuchstaben?
YakovL
1

Jede Veranstaltung hat also Vor- und Nachteile. Die Ereignisse onkeypressund onkeydownrufen nicht den neuesten Wert ab und werden onkeypressin einigen Browsern nicht für nicht druckbare Zeichen ausgelöst. Dasonkeyup Ereignis erkennt nicht, wenn eine Taste für mehrere Zeichen gedrückt gehalten wird.

Das ist ein bisschen hacky, aber so etwas zu tun

function edValueKeyDown(input) {
    var s = input.value;

    var lblValue = document.getElementById("lblValue");
    lblValue.innerText = "The text box contains: "+s;

    //var s = $("#edValue").val();
    //$("#lblValue").text(s);    
}
<input id="edValue" type="text" onkeydown="setTimeout(edValueKeyDown, 0, this)" />

scheint mit dem Besten aller Welten umzugehen.

dx_over_dt
quelle
1

Mit event.key können wir Werte vor der Eingabe in das HTML- Eingabetextfeld abrufen . Hier ist der Code.

function checkText()
{
  console.log("Value Entered which was prevented was - " + event.key);
  
  //Following will prevent displaying value on textbox
  //You need to use your validation functions here and return value true or false.
  return false;
}
<input type="text" placeholder="Enter Value" onkeypress="return checkText()" />

vibs2006
quelle
Dies fällt auseinander, wenn der Text durch etwas geändert wird, das kein Tastendruck ist (Ausschneiden, Einfügen, Löschen ausgewählt usw.)
Ian Boyd
@ IanBoyd stimmte ja zu. Um das Beispiel einfach zu halten, habe ich nur Tastendruckvalidierungen implementiert.
Vibs2006
0

Versuchen Sie, das Ereignis charCode mit dem Wert zu verknüpfen, den Sie erhalten. Hier ist ein Beispiel meines Codes:

<input type="text" name="price" onkeypress="return (cnum(event,this))" maxlength="10">
<p id="demo"></p>

js:

function cnum(event, str) {
    var a = event.charCode;
    var ab = str.value + String.fromCharCode(a);
    document.getElementById('demo').innerHTML = ab;
}

Der Wert in aberhält den neuesten Wert im Eingabefeld.

Rama Krishna
quelle
Entschuldigung, ich habe einen weiteren Beitrag mit noch besserem Ansatz auf dieser Seite bemerkt, nachdem ich diesen gepostet habe. Das habe ich vor dem Posten nicht gesehen. Aber ich denke, mein Konzept ist einfacher zu verstehen.
Rama Krishna
Das fällt auseinander ziemlich schnell , wenn der Schlüssel löschen , Backspace , Strg + X oder Strg + V , oder , wenn die Maus den ganzen Text ausgewählt und i drücken Raum
Ian Boyd
Ich habe gerade meine Idee geschrieben. Sie können es entsprechend Ihren Anforderungen mithilfe von Schlüsselcodes oder anderen Methoden implementieren. Das ist nur meine Idee.
Rama Krishna
1
Ideen sind keine Antworten. Antworten auf SO sollten prägnante Lösungen sein, die die Frage des OP definitiv beantworten, damit jeder davon profitieren kann. Dies erfüllt diese Kriterien eindeutig nicht.
CubicleSoft
0

Es gibt einen besseren Weg, dies zu tun. Verwenden Sie die Concat-Methode. Beispiel

Deklarieren Sie eine globale Variable. Dies funktioniert gut bei Winkel 10, übergeben Sie es einfach an Vanilla JavaScript. Beispiel:

HTML

<input id="edValue" type="text" onKeyPress="edValueKeyPress($event)"><br>
<span id="lblValue">The text box contains: </span>

CODE

emptyString = ''

edValueKeyPress ($event){
   this.emptyString = this.emptyString.concat($event.key);
   console.log(this.emptyString);
}
Abraham Velazquez
quelle
Und wenn der Schlüssel ist Delete, Ctrl+ X, Ctrl+ V, Backspace? Oder wenn sie einen Text ausgewählt haben und dann drücken A?
Ian Boyd