OnKeyPress sırasında bir giriş metin kutusunun metni nasıl alınır?


87

Kullanıcı yazdıkça bir metin kutusundaki metni almaya çalışıyorum ( jsfiddle oyun alanı ):

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 olması dışında hatasız çalıştığını değeri arasında input textesnasında kutunun onKeyPressdeğeri her zaman olduğu öncesi değişim:

görüntü açıklamasını buraya girin

Soru : sırasında bir metin kutusunun metnini nasıl alırım onKeyPress?

Bonus Chatter

HTML DOM'da "kullanıcı yazıyor" ile ilgili üç olay vardır :

  • onKeyDown
  • onKeyPress
  • onKeyUp

In Windows'un , sırası WM_Keykullanıcı tuşunu basılı tutar ve anahtar tekrar başladığında mesajların önemli hale:

  • WM_KEYDOWN('a')- kullanıcı Atuşa bastı
  • WM_CHAR('a')- kullanıcıdan bir akarakter alındı
  • WM_CHAR('a')- kullanıcıdan bir akarakter alındı
  • WM_CHAR('a')- kullanıcıdan bir akarakter alındı
  • WM_CHAR('a')- kullanıcıdan bir akarakter alındı
  • WM_CHAR('a')- kullanıcıdan bir akarakter alındı
  • WM_KEYUP('a')- kullanıcı Aanahtarı serbest bıraktı

Bir metin denetiminde görünen beş karakterle sonuçlanır: aaaaa

Önemli olan nokta, WM_CHARmesaja cevap vermeniz , tekrarlayan olmasıdır. Aksi takdirde, bir tuşa basıldığında olayları kaçırırsınız.

In HTML işler biraz daha farklıdır:

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

Html bir KeyDownve KeyPressher anahtarın tekrarı sunar . Ve KeyUpolay yalnızca kullanıcı anahtarı bıraktığında ortaya çıkar.

Paketler

  • Ben yapabilirsiniz cevap onKeyDownya onKeyPress, ama daha önce de hala yetiştirilir input.valuegüncellendi
  • Cevap veremiyorum onKeyUpçünkü metin kutusundaki metin değiştikçe bu gerçekleşmiyor.

Soru: sırasında bir metin kutusunun metnini nasıl alırım onKeyPress?

Bonus Okuma


1
Döndürmeden önce geçerli tuş basışını değere eklemeniz gerektiğine inanıyorum; değer keyUp'ta güncellenir, ancak veriler size keyDown'da sunulur.
Matematik

Eğer kabartmak eklemek ister sürece benim için Anahtar yukarı işleri, sen böyle bir şey için jQ gerekmez
Ryan B

göreviniz için yalnızca onKeyUp yeterli
dmytro

@mit Yalnızca işleme onKeyUp, metin kutusunda meydana gelen değişiklikleri göstermez.
Ian Boyd

Herhangi bir tuşu basılı tutmak ve metin kutusunda sonuç almak istiyorsanız, çünkü hem onKeyPress hem de onKeyDown olaylarını kullanmalısınız Jonathan M'nin kemanını , ancak tuşları basılı tutmadan sonuç almak istiyorsanız, sadece onKeyUp benim kemanım yeterlidir .
dmytro

Yanıtlar:


20

inputEtkinliği yönetmek tutarlı bir çözümdür: Tüm çağdaş tarayıcılarda ve öğeleri için desteklenirtextarea ve tam olarak ihtiyacınız olduğunda inputtetiklenir :

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>

Yine de bunu biraz yeniden yazardım:

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>


54

Basit tutun. İkisini de kullanın onKeyPress()ve onKeyUp():

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

Bu, en güncel dize değerini (tuş açıldıktan sonra) elde etmeyi sağlar ve ayrıca kullanıcı bir tuşu basılı tutarsa ​​da güncellenir.

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


Arnaud576875'in cevabı vazgeçmek ve geri dönmek zorunda kaldığından onKeyUp(kullanma amacını bozarak onKeypress), bu herkesin göreceği en basit, en temiz ve en yakın cevaptır. Yalnızca en dikkatli gözlemci kullanıcı, geri bildirimlerin girdikleriyle eşleşmediğini fark edecektir.
Ian Boyd

@ Ian, yardımcı olduğuma sevindim. "Geri bildirim girdikleriyle uyuşmuyor" derken neyi kastediyorsunuz? Bir ayarlama gerekli mi?
Jonathan M

şimdi ne demek istediğimi hatırlıyorum! Gitmek istediğim geri bildirim, <input>öğeyi kırmızı veya yeşile boyamak veya kullanıcıya yazdıklarının iyi veya kötü olduğuna dair başka geri bildirimler vermek olabilir. Kabul ettiğiniz cevabınız hala her zaman "tek tek" karakter olma sorunundan muzdarip olsa da, yalnızca en dikkatli kullanıcı geri bildirimin girdikleriyle eşleşmediğini fark edecek. " Gerçekte, ara sıra tek hata yalnızca anahtar tekrarı sırasında olur (yani anahtarı basılı tutuyorlar) kimse (benden başka) sorunu fark
etmeyecek

19

giriş metin kutusunun değeri, onKeyPress sırasında her zaman değişiklikten önceki değerdir

Bu amaç içindir: Bu, olay dinleyicisinin tuşa basmayı iptal etmesine izin verir.

Olay dinleyicileri olayı iptal ederse, değer güncellenmez. Olay iptal edilmezse, değer güncellenir, ancak olay dinleyicisi çağrıldıktan sonra .

Alan değeri güncellendikten sonra değeri almak için, sonraki olay döngüsünde çalışacak bir işlev planlayın. Bunu yapmanın olağan yolu, setTimeoutzaman aşımıyla aramaktır 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);
});

Burada deneyin: http://jsfiddle.net/Q57gY/2/

Düzenleme : Bazı tarayıcılar (ör. Chrome) geri alma için tuşa basma olaylarını tetiklemez; tuşa basma, kodda anahtarlama olarak değiştirildi.


Bunu göndermek üzereydi. İşte yaptığım jsFiddle .
kapa

Haklısınız, Chrome geri tuşu için tuşa basma olaylarını tetiklemiyor gibi görünüyor; güncellendi
Arnaud Le Blanc

@ Ian, OP bir tuş basılı tutulduğunda güncellenmesini istiyor mu? Bunun bir gereklilik olup olmadığından pek emin değildim. Yine de bu çözümün bu işlevselliği yok.
Jonathan M

Açık olmak gerekirse: Geri boşluk için tuşa basma olaylarının tetiklenmemesi Standart: "karakter değeri üreten anahtar" - diğer tuşlar için "keydown" (değiştirmeden önce, iptal edilebilir) veya "keyup" (değişiklikten sonra) kullanın
sebilasse

5

Kompakt tutun.
Bir tuşa her bastığınızda, işlev edValueKeyPress()çağrılır.
Ayrıca, bu işlevde bazı değişkenleri tanımladınız ve başlattınız - bu da süreci yavaşlatır ve daha fazla CPU ve bellek gerektirir.
Basit bir ikameden türetilen bu kodu kullanabilirsiniz.

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

Tüm istediğin bu ve daha hızlı!


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>

3

Şimdiye kadar hiçbir cevap tam bir çözüm sunmuyor. Ele alınması gereken birkaç konu var:

  1. Tüm tuş basışları keydownve keypressişleyiciler aktarılmaz (örneğin, geri alma ve silme tuşları bazı tarayıcılar tarafından bastırılır).
  2. Taşıma keydowniyi bir fikir değil. Bir tuşa basmanın bir tuşa basılmasına neden OLMADIĞI durumlar vardır!
  3. setTimeout() stil çözümleri, kullanıcı yazmayı bırakana kadar Google Chrome / Blink web tarayıcıları altında ertelenir.
  4. Kes, kopyala ve yapıştır gibi eylemleri gerçekleştirmek için fare ve dokunma olayları kullanılabilir. Bu olaylar klavye olaylarını tetiklemeyecektir.
  5. Tarayıcı, giriş yöntemine bağlı olarak, kullanıcı alandan uzaklaşana kadar öğenin değiştiğine dair bildirim göndermeyebilir.

Daha doğru bir çözüm idare edecek keypress, keyup, input, ve changeolayları.

Misal:

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

Vaktini boşa harcamak:

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

Dört olayın tümünü işlemek, tüm uç durumları yakalar. Bir kullanıcıdan gelen girdiyle çalışırken, her tür giriş yöntemi dikkate alınmalı ve tarayıcılar arası ve cihazlar arası işlevsellik doğrulanmalıdır. Yukarıdaki kod, sahip olduğum mobil cihazların yanı sıra masaüstünde Firefox, Edge ve Chrome'da test edildi.


Neden sadece inputolay değil ?
YakovL

inputher zaman ateş etmez. Tek bir olay tüm durumları kapsamaz.
CubicleSoft

daha ayrıntılı olarak "her zaman değil" açıklamak eğer için belirtilen gibi, içinizden güzel olurdu keypressyanıtında
YakovL

1

Normalde alanın değerini (yani güncellenmeden önce) anahtar olayı ile ilişkili anahtarla birleştiririm. Aşağıdakiler en son JS'yi kullanır, bu nedenle eski IE'lerde destek için ayarlama yapılması gerekir.

Son JS örneği

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

Daha eski IE'ler için destek örneği

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

[DÜZENLE - bu yaklaşım, varsayılan olarak, geri boşluk, CTRL + A gibi şeyler için tuşlara basmayı devre dışı bırakır. Yukarıdaki kod, ilkini barındırır, ancak ikincisine ve birkaç başka olasılığa izin vermek için daha fazla düzeltmeye ihtiyaç duyacaktır. Ian Boyd'un yorumuna bakın.]


1
@ bažmegakapa Veya deletetuşu ile veya kullanıcı içeriği değiştirmeyen bir tuşa basarsa ( Ctrl+A) veya kullanıcı bir metin seçer ve ardından abir alt kümeyi değiştirmek için basarsa . Bu iyi bir fikir Utkanos, ama kırılgan bir fikir.
Ian Boyd

1
Kabul. İçinde bir miktar mesafe olduğu için onu bırakacağım, ancak sizin de söylediğiniz gibi, bu uyarılar için ödenek oluşturmalısınız.
Mitya

1

kolay...

KeyPress olay işleyicinizde, yazın

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
}

Ne olur e.KeyCharise Backspaceanahtar? Veya Deleteanahtar? Veya Ctrl+A?
Ian Boyd

Bu JavaScript bile mi? void? object? birinci büyük harf yöntemleri?
YakovL

1

Yani her olayın avantajları ve dezavantajları vardır. Olaylar onkeypressve onkeydownen son değeri alınamadı ve do onkeypressbazı tarayıcılarda olmayan basılabilir karakterler için ateş yapmaz. onkeyupBir anahtar birden çok karakter için basılı tutulduğunda olay algılamaz.

Bu biraz karmaşık, ancak şunun gibi

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

tüm dünyaların en iyisi gibi görünüyor.


1

Event.key kullanarak HTML Girdi Metin Kutusu'na girmeden önce değerleri alabiliriz. İşte 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()" />


Bu metin bir şey aracılığıyla değiştirildiğinde yıkılır değil (kesme, yapıştırma, seçilen silme, vs) bir tuşa basma
Ian Boyd

@IanBoyd evet kabul etti. Örneği basit tutmak için yalnızca tuşa basma doğrulamalarını uyguladım.
vibs2006

0

CharCode olayını aldığınız değerle birleştirmeyi deneyin. İşte kodumun bir örneği:

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

Değer abgiriş alanına en son değeri alacak.


Üzgünüm, bunu gönderdikten sonra bu sayfada daha da iyi bir yaklaşımla başka bir gönderi fark ettim. Bunu göndermeden önce görmedim. Ama sanırım benimki kavramı anlamak daha kolay.
Rama Krishna

Anahtarıdır o zaman oldukça hızlı yıkılır silme , geri silme , Ctrl + X veya Ctrl + V veya fare tüm metin seçilir ve ne zaman i basın Uzay
Ian Boyd

Sadece fikrimi yazdım. Anahtar kodları veya diğer yöntemleri kullanarak ihtiyacınıza göre uygulayabilirsiniz. Bu sadece benim fikrim.
Rama Krishna

1
Fikirler cevap değildir. SO ile ilgili cevaplar, herkesin yararlanabilmesi için OP'nin sorusuna kesin olarak cevap veren kısa çözümler olmalıdır. Bu açıkça bu kriterleri karşılamıyor.
CubicleSoft

0

Bunu yapmanın daha iyi bir yolu var. Concat Yöntemini kullanın. Misal

genel bir değişken bildirir. bu açısal 10'da iyi çalışır, sadece Vanilla JavaScript'e aktarın. Misal:

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

Ve anahtar olduğunda Delete, Ctrl+ X, Ctrl+ V, Backspace? Veya bir metin seçip ardından tuşuna bastılarsa A?
Ian Boyd
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.