如何在 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') - 用户按下了 AWM_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 提供KeyDownKeyPress 每个键重复。并且KeyUp 事件仅在用户释放键时引发。

外卖

可以回复 onKeyDownonKeyPress,但在 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 用于所有当代浏览器中的textareainput 元素,它会在您需要时触发准确: 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 中的值将获取输入字段中的最新值。

【讨论】:

抱歉,在我发布此内容后,我注意到此页面中的另一篇帖子采用了更好的方法。发帖之前没看到但我认为我的概念更容易理解。 当键是 deletebackspaceCtrl+XCtrl 时,它很快就崩溃了+V,或者当鼠标选中所有文本并且我按下 Space 我刚刚写下了我的想法。您可以根据您的要求使用键码或其他方法来实现它。这只是我的想法。 想法不是答案。 SO的答案应该是明确回答OP问题的简洁解决方案,以便每个人都可以受益。这显然不符合该标准。 String.fromCharCode(a) 的好主意。谢谢。【参考方案4】:

保持紧凑。 每按一次键,就会调用函数edValueKeyPress()。 您还在该函数中声明并初始化了一些变量 - 这会减慢进程并需要更多 CPU 和内存。 您可以简单地使用此代码 - 源自简单替换。

function edValueKeyPress()

    document.getElementById("lblValue").innerText =""+document.getElementById("edValue").value;

这就是你想要的,而且速度更快!

【讨论】:

【参考方案5】:

到目前为止,没有一个答案提供完整的解决方案。有很多问题需要解决:

    并非所有按键都传递到 keydownkeypress 处理程序(例如,退格键和删除键被某些浏览器禁止)。 处理keydown 不是一个好主意。在某些情况下,按键不会导致按键! setTimeout() 风格的解决方案在 Google Chrome/Blink 网络浏览器下会延迟,直到用户停止输入。 鼠标和触摸事件可用于执行剪切、复制和粘贴等操作。这些事件不会触发键盘事件。 在用户离开该字段之前,浏览器可能不会发送元素已更改的通知,具体取决于输入法。

更正确的解决方案将处理keypresskeyupinputchange 事件。

例子:

<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;
&lt;input type="text" placeholder="Enter Value" onkeypress="return checkText()" /&gt;

【讨论】:

当文本通过按键(剪切、粘贴、删除选定内容等)更改文本时,这会崩溃 @IanBoyd 同意。为了使示例简单,我只实现了按键验证。【参考方案7】:

保持简单。同时使用onKeyPress()onKeyUp()

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

这负责获取最新的字符串值(在按键之后),并且如果用户按住按键也会更新。

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

【讨论】:

由于 arnaud576875 的答案不得不放弃并退回到onKeyUp(违背了使用onKeypress 的目的),这是任何人都会看到的最简单、最干净和最接近的答案。只有最仔细观察的用户才会注意到反馈与他们输入的内容不符。 @Ian,很高兴为您提供帮助。 “反馈与他们输入的内容不符”是什么意思?需要调整吗? 我现在记住了我的意思!我所指的反馈是将&lt;input&gt; 元素着色为红色或绿色,或者向用户提供一些其他反馈,说明他们输入的内容是好是坏。虽然您接受的答案仍然存在始终是 "off-by-one" 字符的问题:只有最细心的用户会注意到反馈与他们输入的内容不匹配。 " 实际上,由于逐个错误只发生在重复键期间(即他们按住键),没有人(除了我之外)会注意到这个问题。【参考方案8】:

所以每个事件都有优点和缺点。事件onkeypressonkeydown 不会检索最新值,并且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.KeyCharBackspace 键会怎样?还是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 期间获取输入文本框的文本?的主要内容,如果未能解决你的问题,请参考以下文章

文本框中,回车键触发事件的js代码[多浏览器兼容]

如何获取C++中文本输入框的内容

文本框获得焦点时,显示旁边的文字

c++获取文本框的值

MFC如何从文本框中获取数字

如何获取HTML中用户输入到文本框中的内容?