如何在 onKeyPress 期间获得输入文本框的文本?

我试图得到一个文本框中的文本作为用户键入它(Jsfiddle 游乐场) :

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>

该代码运行没有错误,除了 input text框的 < em > value ,在 onKeyPress期间总是值 之前的变化:

enter image description here

问题 : 如何在 onKeyPress期间获得文本框的文本?

额外的闲聊

HTML DOM 中有三个与 “用户正在输入”相关的事件:

  • onKeyDown
  • onKeyPress
  • onKeyUp

窗户中,当用户按住一个键并且该键开始重复时,WM_Key消息的顺序就变得很重要:

  • 用户按下了 A
  • WM_CHAR('a')-从用户处收到一个 a字符
  • WM_CHAR('a')-从用户处收到一个 a字符
  • WM_CHAR('a')-从用户处收到一个 a字符
  • WM_CHAR('a')-从用户处收到一个 a字符
  • WM_CHAR('a')-从用户处收到一个 a字符
  • WM_KEYUP('a')-用户已经释放了 A

将导致文本控件中出现五个字符: aaaaa

重要的一点是,您要响应 WM_CHAR消息,即重复的那条消息。否则,按下键时将错过事件。

超文本标示语言中,情况略有不同:

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

HTML 提供一个 KeyDownKeyPress每个键重复。只有当用户释放密钥时才会引发 KeyUp事件。

带走

  • I 可以响应于 onKeyDownonKeyPress,但是在 input.value被更新之前,它们仍然被提升
  • 我无法响应 onKeyUp,因为它不会随着文本框中文本的变化而发生。

问题: onKeyPress中如何获得文本框的文本?

额外阅读

312633 次浏览

the value of the input text box, during onKeyPress is always the value before the change

This is on purpose: This allows the event listener to cancel the keypress.

If the event listeners cancels the event, the value is not updated. If the event is not canceled, the value is updated, but after the event listener was called.

To get the value after the field value has been updated, schedule a function to run on the next event loop. The usual way to do this is to call setTimeout with a timeout of 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);
});

Try here: http://jsfiddle.net/Q57gY/2/

Edit: Some browsers (e.g. Chrome) do not trigger keypress events for backspace; changed keypress to keyup in code.

Keep it simple. Use both onKeyPress() and onKeyUp():

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

This takes care of getting the most updated string value (after key up) and also updates if the user holds down a key.

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

I normally concatenate the field's value (i.e. before it's updated) with the key associated with the key event. The following uses recent JS so would need adjusting for support in older IE's.

Recent JS example

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

Support for older IEs example

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

[EDIT - this approach, by default, disables key presses for things like back space, CTRL+A. The code above accommodates for the former, but would need further tinkering to allow for the latter, and a few other eventualities. See Ian Boyd's comment below.]

easy...

In your keyPress event handler, write

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

keep it Compact.
Each time you press a key, the function edValueKeyPress() is called.
You've also declared and initialized some variables in that function - which slow down the process and requires more CPU and memory as well.
You can simply use this code - derived from simple substitution.

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

That's all you want, and it's faster!

So there are advantages and disadvantages to each event. The events onkeypress and onkeydown don't retrieve the latest value, and onkeypress doesn't fire for non-printable characters in some browsers. The onkeyup event doesn't detect when a key is held down for multiple characters.

This is a little hacky, but doing something like

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

seems to handle the best of all worlds.

Try to concatenate the event charCode to the value you get. Here is a sample of my code:

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

The value in ab will get the latest value in the input field.

By using event.key we can get values prior entry into HTML Input Text Box. Here is the 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()" />

None of the answers so far offer a complete solution. There are quite a few issues to address:

  1. Not all keypresses are passed onto keydown and keypress handlers (e.g. backspace and delete keys are suppressed by some browsers).
  2. Handling keydown is not a good idea. There are situations where a keydown does NOT result in a keypress!
  3. setTimeout() style solutions get delayed under Google Chrome/Blink web browsers until the user stops typing.
  4. Mouse and touch events may be used to perform actions such as cut, copy, and paste. Those events will not trigger keyboard events.
  5. The browser, depending on the input method, may not deliver notification that the element has changed until the user navigates away from the field.

A more correct solution will handle the keypress, keyup, input, and change events.

Example:

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

Fiddle:

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

Handling all four events catches all of the edge cases. When working with input from a user, all types of input methods should be considered and cross-browser and cross-device functionality should be verified. The above code has been tested in Firefox, Edge, and Chrome on desktop as well as the mobile devices I own.

Handling the input event is a consistent solution: it is supported for textarea and input elements in all contemporary browsers and it fires exactly when you need it:

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>

I'd rewrite this a bit, though:

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

There is a better way to do this. Use the concat Method. Example

declare a global variable. this works good on angular 10, just pass it to Vanilla JavaScript. Example:

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