Jak uzyskać tekst z pola tekstowego podczas onKeyPress?

85

Próbuję uzyskać tekst w polu tekstowym, gdy użytkownik w nim wpisuje ( jsfiddle zabaw ):

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>

Kod działa bez błędów, z wyjątkiem, że wartości w input textpolu, w czasie onKeyPressjest zawsze wartość przed zmianą:

wprowadź opis obrazu tutaj

Pytanie : Jak uzyskać tekst pola tekstowego w trakcie onKeyPress?

Bonus Chatter

Istnieją trzy zdarzenia związane ze słowem „użytkownik pisze” w HTML DOM:

  • onKeyDown
  • onKeyPress
  • onKeyUp

W systemie Windows kolejność WM_Keykomunikatów staje się ważna, gdy użytkownik przytrzymuje klawisz, a klucz zaczyna się powtarzać:

  • WM_KEYDOWN('a')- użytkownik nacisnął Aklawisz
  • WM_CHAR('a')- apostać została odebrana od użytkownika
  • WM_CHAR('a')- apostać została odebrana od użytkownika
  • WM_CHAR('a')- apostać została odebrana od użytkownika
  • WM_CHAR('a')- apostać została odebrana od użytkownika
  • WM_CHAR('a')- apostać została odebrana od użytkownika
  • WM_KEYUP('a')- użytkownik zwolnił Aklucz

Spowoduje, że w kontrolce tekstowej pojawi się pięć znaków: aaaaa

Ważne jest to, że odpowiadasz na WM_CHARwiadomość, tę, która się powtarza. W przeciwnym razie przegapisz wydarzenia po naciśnięciu klawisza.

W HTML sprawy wyglądają nieco inaczej:

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

Html dostarcza KeyDowni KeyPresskażdy klucz powtórki. A KeyUpzdarzenie jest wywoływane tylko wtedy, gdy użytkownik zwolni klawisz.

Na wynos

  • I może reagować na onKeyDownlub onKeyPress, ale oba są jeszcze podniesiona, zanim input.valuezostał zaktualizowany
  • Nie mogę odpowiedzieć onKeyUp, ponieważ nie dzieje się tak, gdy zmienia się tekst w polu tekstowym.

Pytanie: Jak uzyskać tekst pola tekstowego w trakcie onKeyPress?

Czytanie bonusowe

Ian Boyd
źródło
1
Uważam, że przed zwróceniem wartości należy dołączyć bieżące naciśnięcie klawisza do wartości; wartość jest aktualizowana w keyUp, ale dane są dostępne dla Ciebie w keyDown.
Mathletics
U mnie klawiszowanie działa, nie potrzebujesz jQ do czegoś takiego, chyba że lubisz dodawać wzdęcia
Ryan B
wystarczy tylko onKeyUp do twojego zadania
dmytro
Obsługa @mit Only onKeyUpnie pokazuje zmian w polu tekstowym w momencie, gdy zachodzą.
Ian Boyd,
jeśli chcesz przytrzymać dowolny klawisz i uzyskać wynik w polu tekstowym, z tego powodu powinieneś użyć zarówno zdarzeń onKeyPress, jak i onKeyDown skrzypiec Jonathana M , ale jeśli chcesz uzyskać wynik bez przytrzymywania klawiszy, wystarczy tylko onKeyUp moje skrzypce .
dmytro

Odpowiedzi:

19

Obchodzenie się z inputzdarzenie jest spójne rozwiązanie: jest on wspierany przez textareai inputelementy we wszystkich współczesnych przeglądarkach i pożary dokładnie , kiedy trzeba go:

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>

Jednak przepisałbym to trochę:

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
źródło
54

Nie komplikuj. Użyj obu onKeyPress()i onKeyUp():

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

Dba o to, aby uzyskać najbardziej zaktualizowaną wartość ciągu (po podniesieniu klucza), a także aktualizuje, jeśli użytkownik przytrzyma klucz.

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

Jonathan M
źródło
Ponieważ odpowiedź arnaud576875 musiała się poddać i wycofać onKeyUp(pokonując cel użycia onKeypress), jest to najprostsza, najczystsza i najbliższa odpowiedź, jaką ktokolwiek zobaczy. Tylko najbardziej uważny użytkownik zauważy, że opinia nie zgadza się z tym, co wprowadził.
Ian Boyd,
@Ian, cieszę się, że mogę pomóc. Co masz na myśli, mówiąc „opinie nie zgadzają się z wprowadzonymi”? Czy potrzebne jest dostosowanie?
Jonathan M
Pamiętam, co miałem teraz na myśli! Opinia, o której mówię, będzie polegała na zabarwieniu <input>elementu na czerwono lub zielono lub przekazaniu użytkownikowi innej opinii, że to, co wpisał, jest dobre lub złe. Twoja zaakceptowana odpowiedź nadal boryka się z problemem polegającym na tym, że zawsze jesteś „osobnym” znakiem: tylko najbardziej spostrzegawczy użytkownik zauważy, że informacja zwrotna nie zgadza się z tym, co wprowadził. ” W rzeczywistości, ponieważ jeden błąd zdarza się tylko podczas kluczowego-repeat (tj oni przytrzymanie klawisza w dół) nikt (oprócz mnie) nie zauważy problem.
Ian Boyd
19

wartość pola tekstowego wejściowego, podczas onKeyPress jest zawsze wartością przed zmianą

Jest to celowe: umożliwia detektorowi zdarzeń anulowanie naciśnięcia klawisza.

Jeśli detektory zdarzeń anulują zdarzenie , wartość nie jest aktualizowana. Jeśli zdarzenie nie zostanie anulowane, wartość jest aktualizowana, ale po wywołaniu detektora zdarzenia .

Aby uzyskać wartość po zaktualizowaniu wartości pola, zaplanuj uruchomienie funkcji w następnej pętli zdarzeń. Zwykle można to zrobić, dzwoniąc setTimeoutz limitem czasu wynoszącym 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);
});

Spróbuj tutaj: http://jsfiddle.net/Q57gY/2/

Edycja : Niektóre przeglądarki (np. Chrome) nie wyzwalają zdarzeń naciśnięcia klawisza dla Backspace; zmieniono naciśnięcie klawisza na wprowadzenie kodu.

Arnaud Le Blanc
źródło
Miałem to opublikować. Oto jsFiddle, które zrobiłem.
kapa
Masz rację, wydaje się, że Chrome nie wywołuje zdarzeń naciśnięcia klawisza dla Backspace; zaktualizowane
Arnaud Le Blanc,
@Ian, czy OP chce, aby był aktualizowany, gdy klawisz jest przytrzymywany? Nie byłem pewien, czy to był wymóg. To rozwiązanie nie ma jednak takiej funkcjonalności.
Jonathan M
Dla jasności: nie wyzwalanie zdarzeń naciśnięcia klawisza dla klawisza Backspace jest zgodne ze standardem: „klawisz, który tworzy wartość
znakową
5

Keep it Compact.
Za każdym naciśnięciem klawisza edValueKeyPress()wywoływana jest funkcja .
Zadeklarowałeś również i zainicjowałeś niektóre zmienne w tej funkcji - co spowalnia proces i wymaga więcej procesora i pamięci.
Możesz po prostu użyć tego kodu - pochodzącego z prostego podstawienia.

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

To wszystko, czego chcesz, i to szybciej!

Wajahath
źródło
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 pal
źródło
3

Żadna z dotychczasowych odpowiedzi nie oferuje pełnego rozwiązania. Jest kilka problemów do rozwiązania:

  1. Nie wszystkie naciśnięcia klawiszy są przekazywane do keydowni keypressprocedury obsługi (np. Klawisze cofania i usuwania są blokowane przez niektóre przeglądarki).
  2. Obsługa keydownnie jest dobrym pomysłem. Są sytuacje, w których upadek klawisza NIE powoduje naciśnięcia klawisza!
  3. setTimeout() rozwiązania stylistyczne są opóźniane w przeglądarkach internetowych Google Chrome / Blink do momentu, gdy użytkownik przestanie pisać.
  4. Zdarzenia myszy i dotyku mogą służyć do wykonywania czynności, takich jak wycinanie, kopiowanie i wklejanie. Te zdarzenia nie wywołają zdarzeń klawiatury.
  5. Przeglądarka, w zależności od metody wprowadzania, może nie dostarczyć powiadomienia o zmianie elementu, dopóki użytkownik nie opuści pola.

Bardziej poprawne rozwiązanie będzie obsługiwać keypress, keyup, inputoraz changewydarzenia.

Przykład:

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

Skrzypce:

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

Obsługa wszystkich czterech zdarzeń obejmuje wszystkie przypadki skrajne. Podczas pracy z danymi wejściowymi od użytkownika należy wziąć pod uwagę wszystkie typy metod wprowadzania i zweryfikować funkcjonalność między przeglądarkami i urządzeniami. Powyższy kod został przetestowany w Firefoksie, Edge i Chrome na komputerach stacjonarnych, a także na posiadanych przeze mnie urządzeniach mobilnych.

CubicleSoft
źródło
Dlaczego nie tylko inputwydarzenie?
YakovL
inputnie zawsze strzela. Żadne wydarzenie nie obejmuje wszystkich sytuacji.
CubicleSoft
byłoby miło z twojej strony, gdybyś opisał „nie zawsze” bardziej szczegółowo, tak jak określiłeś keypressw odpowiedzi
JakowL,
1

Zwykle łączę wartość pola (tj. Przed jego aktualizacją) z kluczem skojarzonym ze zdarzeniem klucza. Poniższy kod używa najnowszego JS, więc będzie wymagał dostosowania do obsługi starszych przeglądarek IE.

Najnowszy przykład JS

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

Wsparcie dla starszych przykładów IE

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

[EDYCJA - to podejście domyślnie wyłącza naciskanie klawiszy dla rzeczy takich jak spacja, CTRL + A. Powyższy kod uwzględnia ten pierwszy, ale wymagałby dalszego majstrowania, aby umożliwić drugie, i kilka innych ewentualności. Zobacz komentarz Iana Boyda poniżej.]

Mitya
źródło
1
@ bažmegakapa Lub za pomocą deleteklawisza, lub jeśli użytkownik naciśnie klawisz, który nie modyfikuje zawartości ( Ctrl+A), lub jeśli użytkownik zaznaczy jakiś tekst, a następnie naciśnie, aaby zastąpić podzbiór. To dobry pomysł, Utkanos, ale kruchy.
Ian Boyd
1
Zgoda. Zostawię to, ponieważ jest w tym pewien przebieg, ale, jak powiedziałeś, musiałbyś uwzględnić te ograniczenia.
Mitya
1

łatwy...

W programie obsługi zdarzeń keyPress napisz

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
źródło
Co się stanie, jeśli e.KeyCharjest Backspaceklucz? Albo Deleteklucz? Albo Ctrl+A?
Ian Boyd
Czy to w ogóle JavaScript? void? object? metody wykorzystujące pierwsze wielkie litery?
YakovL
1

Każda impreza ma więc wady i zalety. Zdarzenia onkeypressi onkeydownnie pobierają najnowszej wartości i onkeypressnie są uruchamiane w przypadku znaków niedrukowalnych w niektórych przeglądarkach. onkeyupWydarzenie nie wykrywa, gdy klawisz jest wciśnięty do wielu znaków.

To trochę dziwne, ale robię coś takiego

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)" />

wydaje się obsługiwać to, co najlepsze ze wszystkich światów.

dx_over_dt
źródło
1

Używając event.key możemy uzyskać wartości przed wejściem do pola tekstowego HTML Input. Oto kod.

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
źródło
Rozpada się, gdy tekst jest zmieniany za pomocą czegoś, co nie jest naciśnięciem klawisza (wytnij, wklej, usuń zaznaczone itp.)
Ian Boyd
@IanBoyd tak się zgodził. Aby zachować prosty przykład, zaimplementowałem tylko walidację naciśnięcia klawisza.
vibs2006
0

Spróbuj połączyć zdarzenie charCode z otrzymaną wartością. Oto próbka mojego kodu:

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

Wartość w abotrzyma ostatnią wartość w polu wejściowym.

Rama Krishna
źródło
Przepraszam, zauważyłem inny post z jeszcze lepszym podejściem na tej stronie po tym, jak go opublikowałem. Nie widziałem tego przed wysłaniem. Ale myślę, że moje jest prostsze do zrozumienia koncepcji.
Rama Krishna,
To dość szybko się rozpada, gdy klawiszem jest delete , backspace , Ctrl + X lub Ctrl + V , lub gdy myszka zaznaczy cały tekst i naciskam spację
Ian Boyd
Właśnie napisałem swój pomysł. możesz go zaimplementować zgodnie z wymaganiami, używając kodów klawiszy lub innych metod. To tylko mój pomysł.
Rama Krishna
1
Pomysły to nie odpowiedzi. Odpowiedzi na SO powinny być zwięzłymi rozwiązaniami, które ostatecznie odpowiadają na pytanie PO, tak aby każdy mógł skorzystać. To oczywiście nie spełnia tych kryteriów.
CubicleSoft
0

Jest na to lepszy sposób. Użyj metody concat. Przykład

zadeklaruj zmienną globalną. działa to dobrze na angular 10, po prostu prześlij to do Vanilla JavaScript. Przykład:

HTML

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

KOD

emptyString = ''

edValueKeyPress ($event){
   this.emptyString = this.emptyString.concat($event.key);
   console.log(this.emptyString);
}
Abraham Velazquez
źródło
A gdy klucz jest Delete, Ctrl+ X, Ctrl+ V, Backspace? Lub jeśli zaznaczyli jakiś tekst, a następnie naciśnij A?
Ian Boyd