如何在 onKeyPress 期间获取输入文本框的文本?
Posted
技术标签:
【中文标题】如何在 onKeyPress 期间获取输入文本框的文本?【英文标题】:How to get text of an input text box during onKeyPress? 【发布时间】:2012-07-07 02:50:06 【问题描述】:我试图在用户输入文本框中获取文本 (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>
代码运行没有错误,除了input text
框的值,在onKeyPress
期间始终是更改之前的值:
问题:
onKeyPress
期间如何获取文本框的文本?
奖金聊天
在 html DOM 中有三个与“用户正在输入”相关的事件:
onKeyDown
onKeyPress
onKeyUp
在 Windows 中,当用户按住某个键并开始重复该键时,WM_Key
消息的顺序变得很重要:
WM_KEYDOWN('a')
- 用户按下了 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
消息,即重复的消息。否则,您会在按下某个键时错过事件。
在 HTML 中略有不同:
onKeyDown
onKeyPress
onKeyDown
onKeyPress
onKeyDown
onKeyPress
onKeyDown
onKeyPress
onKeyDown
onKeyPress
onKeyUp
Html 提供KeyDown
和KeyPress
每个键重复。并且KeyUp
事件仅在用户释放键时引发。
外卖
我可以回复onKeyDown
或 onKeyPress
,但在 input.value
更新之前,这两个问题仍然存在
我无法回复onKeyUp
,因为它不会随着文本框中的文本更改而发生。
问题:如何在onKeyPress
期间获取文本框的文本?
阅读奖励
Getting a form value with jQuery Get the value in an input text box【问题讨论】:
我相信您需要在返回之前将当前按键附加到该值;该值在 keyUp 上得到更新,但数据在 keyDown 上可供您使用。 Key up 对我有用,你不需要 jQ 来做这样的事情,除非你想增加臃肿 你的任务只需要 onKeyUp 就足够了 @mit 仅处理onKeyUp
不会在文本框中显示发生的更改。
如果你想按住任意键并在文本框中得到结果,当然你应该同时使用 onKeyPress 和 onKeyDown 事件Jonathan M's fiddle,但是如果你想在不按住键的情况下得到结果,那就是仅 onKeyUp my fiddle 就够了。
【参考方案1】:
处理input
事件是一个一致的解决方案:它是supported 用于所有当代浏览器中的textarea
和input
元素,它会在您需要时触发准确: p>
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>
不过,我会重写一下:
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>
【讨论】:
【参考方案2】:有更好的方法来做到这一点。使用 concat 方法。示例
声明一个全局变量。这在 angular 10 上效果很好,只需将其传递给 Vanilla javascript。示例:
HTML
<input id="edValue" type="text" onKeyPress="edValueKeyPress($event)"><br>
<span id="lblValue">The text box contains: </span>
代码
emptyString = ''
edValueKeyPress ($event)
this.emptyString = this.emptyString.concat($event.key);
console.log(this.emptyString);
【讨论】:
当密钥是Delete
, Ctrl
+X
, Ctrl
+V
, Backspace
?或者,如果他们选择了一些文本,然后按A
?【参考方案3】:
尝试将事件 charCode 连接到您获得的值。 这是我的代码示例:
<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;
ab
中的值将获取输入字段中的最新值。
【讨论】:
抱歉,在我发布此内容后,我注意到此页面中的另一篇帖子采用了更好的方法。发帖之前没看到但我认为我的概念更容易理解。 当键是 delete、backspace、Ctrl+X 或 Ctrl 时,它很快就崩溃了+V,或者当鼠标选中所有文本并且我按下 Space 我刚刚写下了我的想法。您可以根据您的要求使用键码或其他方法来实现它。这只是我的想法。 想法不是答案。 SO的答案应该是明确回答OP问题的简洁解决方案,以便每个人都可以受益。这显然不符合该标准。 String.fromCharCode(a) 的好主意。谢谢。【参考方案4】:保持紧凑。
每按一次键,就会调用函数edValueKeyPress()
。
您还在该函数中声明并初始化了一些变量 - 这会减慢进程并需要更多 CPU 和内存。
您可以简单地使用此代码 - 源自简单替换。
function edValueKeyPress()
document.getElementById("lblValue").innerText =""+document.getElementById("edValue").value;
这就是你想要的,而且速度更快!
【讨论】:
【参考方案5】:到目前为止,没有一个答案提供完整的解决方案。有很多问题需要解决:
-
并非所有按键都传递到
keydown
和 keypress
处理程序(例如,退格键和删除键被某些浏览器禁止)。
处理keydown
不是一个好主意。在某些情况下,按键不会导致按键!
setTimeout()
风格的解决方案在 Google Chrome/Blink 网络浏览器下会延迟,直到用户停止输入。
鼠标和触摸事件可用于执行剪切、复制和粘贴等操作。这些事件不会触发键盘事件。
在用户离开该字段之前,浏览器可能不会发送元素已更改的通知,具体取决于输入法。
更正确的解决方案将处理keypress
、keyup
、input
和change
事件。
例子:
<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>
小提琴:
http://jsfiddle.net/VDd6C/2175/
处理所有四个事件会捕获所有边缘情况。处理用户输入时,应考虑所有类型的输入法,并验证跨浏览器和跨设备功能。以上代码已经在桌面版的 Firefox、Edge 和 Chrome 以及我拥有的移动设备上进行了测试。
【讨论】:
为什么不只是input
活动?
input
并不总是触发。没有一个事件可以涵盖所有情况。
如果您更详细地描述“并非总是”,您会很好,就像您在答案中为keypress
指定的那样【参考方案6】:
通过使用 event.key,我们可以在输入 HTML 输入文本框之前获取值。这是代码。
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()" />
【讨论】:
当文本通过非按键(剪切、粘贴、删除选定内容等)更改文本时,这会崩溃 @IanBoyd 同意。为了使示例简单,我只实现了按键验证。【参考方案7】:保持简单。同时使用onKeyPress()
和onKeyUp()
:
<input id="edValue" type="text" onKeyPress="edValueKeyPress()" onKeyUp="edValueKeyPress()">
这负责获取最新的字符串值(在按键之后),并且如果用户按住按键也会更新。
jsfiddle:http://jsfiddle.net/VDd6C/8/
【讨论】:
由于 arnaud576875 的答案不得不放弃并退回到onKeyUp
(违背了使用onKeypress
的目的),这是任何人都会看到的最简单、最干净和最接近的答案。只有最仔细观察的用户才会注意到反馈与他们输入的内容不符。
@Ian,很高兴为您提供帮助。 “反馈与他们输入的内容不符”是什么意思?需要调整吗?
我现在记住了我的意思!我所指的反馈是将<input>
元素着色为红色或绿色,或者向用户提供一些其他反馈,说明他们输入的内容是好是坏。虽然您接受的答案仍然存在始终是 "off-by-one" 字符的问题:只有最细心的用户会注意到反馈与他们输入的内容不匹配。 " 实际上,由于逐个错误只发生在重复键期间(即他们按住键),没有人(除了我之外)会注意到这个问题。【参考方案8】:
所以每个事件都有优点和缺点。事件onkeypress
和onkeydown
不会检索最新值,并且onkeypress
在某些浏览器中不会针对不可打印的字符触发。 onkeyup
事件不会检测何时按住多个字符的键。
这有点 hacky,但是做一些类似的事情
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)" />
似乎可以处理所有世界中最好的事情。
【讨论】:
【参考方案9】:<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>
【讨论】:
【参考方案10】:简单...
在您的 keyPress 事件处理程序中,编写
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
【讨论】:
如果e.KeyChar
是Backspace
键会怎样?还是Delete
键?还是Ctrl+A
?
这甚至是 JavaScript 吗? void
? object
?第一个大写方法?【参考方案11】:
我通常将字段的值(即在更新之前)与与键事件关联的键连接起来。以下使用最近的 JS,因此需要调整以支持旧版 IE。
最近的 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);
支持旧版 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);
[编辑 - 默认情况下,这种方法会禁用诸如退格键、CTRL+A 之类的按键。上面的代码适用于前者,但需要进一步修改以允许后者以及其他一些可能性。请参阅下面 Ian Boyd 的评论。]
【讨论】:
@bažmegakapa 或者使用delete
键,或者如果用户按下不修改内容的键(Ctrl+A
),或者如果用户选择一些文本然后按下@987654325 @ 替换子集。这是个好主意,Utkanos,但很脆弱。
同意。我会保留它,因为它有一些里程,但正如你所说,你必须为这些警告建立一些津贴。【参考方案12】:
输入文本框的值,onKeyPress期间始终是改变前的值
这是故意的:这允许事件侦听器取消按键。
如果事件监听器cancels the event,值不会更新。如果事件没有被取消,值会被更新,但是在事件监听器被调用之后。
要在字段值更新后获取值,请安排一个函数在下一个事件循环中运行。通常的方法是调用setTimeout
,超时为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);
);
在这里试试:http://jsfiddle.net/Q57gY/2/
编辑:某些浏览器(例如 Chrome)不会触发退格键事件;在代码中将按键更改为 keyup。
【讨论】:
正要发布这个。这是我做的jsFiddle。 你说得对,Chrome似乎不会触发退格键事件;更新 @Ian,OP 是否希望它在按下键时更新?不太确定这是否是要求。不过,此解决方案没有该功能。 要明确:不触发退格键的按键事件符合标准:“产生字符值的键” - 对于其他键使用“keydown”(更改之前,可取消)或“keyup”(更改后)以上是关于如何在 onKeyPress 期间获取输入文本框的文本?的主要内容,如果未能解决你的问题,请参考以下文章