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


85

我正在尝试在用户输入文本框(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框,期间onKeyPress总是值之前的变化:

在此处输入图片说明

问题:如何在此期间获取文本框的文本onKeyPress

奖金Chat不休

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会提供一个KeyDownKeyPress每个键重复的位置。并且KeyUp仅当用户释放密钥时才引发事件。

外卖

  • 可以回应onKeyDownonKeyPress,但在input.value在进行更新
  • 我无法回应onKeyUp,因为在文本框中的文本更改时不会发生。

问题:在期间,如何获取文本框的文本onKeyPress

奖励阅读


1
我相信您需要在返回值之前将当前按键添加到该值;该值会在keyUp上更新,但可以在keyDown上使用该数据。
数学2012年

密码输入对我有用,除非您喜欢添加膨胀,否则您不需要jQ这样的东西
-Ryan B

仅onKeyUp就足以完成您的任务
dmytro 2014年

@mit仅处理onKeyUp不会在更改时在文本框中显示更改。
伊恩·博伊德 Ian Boyd)

如果您想按住任意键并在文本框中获取结果,则应同时使用onKeyPress和onKeyDown事件Jonathan M的小提琴,但是如果您想要在不按住键的情况下获得结果,仅onKeyUp我的小提琴就足够了。
dmytro 2014年

Answers:


19

处理该input事件是一致的解决方案:它支持用于textareainput所有现代浏览器元素和它触发正是当你需要它:

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("lblValue").innerText = value;
}
<input id="edValue" type="text" onInput="showCurrentValue(event)"><br>
The text box contains: <span id="lblValue"></span>


54

把事情简单化。同时使用onKeyPress()onKeyUp()

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

这样可以确保获得最新的字符串值(在按下键之后),并且在用户按下某个键时也会更新。

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


由于arnaud576875的答案不得不放弃并退而求其次onKeyUp(击败了使用的目的onKeypress),因此这是任何人都会看到的最简单,最简洁和最接近的答案。只有最仔细观察的用户才会注意到反馈与他们输入的内容不匹配。
伊恩·博伊德

@Ian,很高兴能为您提供帮助。“反馈与他们输入的内容不匹配”是什么意思?是否需要调整?
乔纳森·M

我记得我现在的意思!我指的是,该反馈将<input>元素着色为红色或绿色,或者向用户提供其他反馈,表明他们键入的内容是好是坏。尽管您接受的答案仍然会遇到总是一字不漏”的问题:只有最能观察到的用户才会注意到反馈与他们输入的内容不匹配。”实际上,因为一个错误仅在重复键期间发生(即,他们按住了键)没有人(除我以外)不会注意到该问题
Ian Boyd 2012年

19

在onKeyPress期间,输入文本框的值始终是更改前的值

这是有目的的:这允许事件侦听器取消按键。

如果事件侦听器取消了该事件,则不会更新该值。如果未取消事件,那么将在调用事件侦听器之后更新值。

要在更新字段值之后获取该值,请安排一个函数在下一个事件循环上运行。通常的方法是调用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)不会触发退格键事件;将按键更改为代码中的按键。


即将发布。这是我做过的jsFiddle
卡帕2012年

没错,Chrome似乎不会触发退格键事件;已更新
Arnaud Le Blanc

@ Ian,OP是否希望在按下某个键时对其进行更新?不太确定这是否是必要条件。但是,此解决方案没有该功能。
乔纳森·M

需要明确的是:不按退格键触发按键事件是按照Standard进行的:“产生字符值的键”-对于其他键,请使用“ keydown”(更改前可以取消)或“ keyup”(更改后)
sebilasse

5

保持紧凑。
每次您按下一个键,edValueKeyPress()都会调用该功能。
您还已经在该函数中声明和初始化了一些变量-减慢了该过程的速度,并且还需要更多的CPU和内存。
您可以简单地使用此代码-从简单替换派生。

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

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


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

到目前为止,没有任何答案可以提供完整的解决方案。有很多问题要解决:

  1. 并非所有的按键都转嫁给keydownkeypress处理程序(如退格键和Delete键是由某些浏览器抑制)。
  2. 处理keydown不是一个好主意。在某些情况下,按下按键不会导致按键!
  3. setTimeout() 样式解决方案在Google Chrome / Blink网络浏览器中会延迟到用户停止键入为止。
  4. 鼠标和触摸事件可用于执行诸如剪切,复制和粘贴之类的动作。这些事件将不会触发键盘事件。
  5. 取决于输入方法,浏览器可能不会传递元素已更改的通知,直到用户离开该字段为止。

更正确的解决方案将处理keypresskeyupinput,和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事件?
YakovL

input并不总是会开火。没有任何一个事件可以涵盖所有情况。
CubicleSoft

如果您更详细地描述“并非总是”,如您keypress在答案中所指定的那样,那么您会很好
-YakovL

1

我通常将字段的值(即在更新之前)与与键事件关联的键连接在一起。以下使用最新的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的评论。]


1
@bažmegakapa或使用delete键,或者用户按下的键不修改内容(Ctrl+A),或者用户选择了一些文本,然后按下a替换子集。Utkanos,这是个好主意,但比较脆弱。
伊恩·博伊德

1
同意 我会把它保留下来,因为其中有一些里程,但是,正如您所说,您必须为这些警告增加津贴。
Mitya

1

简单...

在您的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吗?voidobject?前大写方法?
YakovL

1

因此,每个事件都有优点和缺点。事件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)" />

似乎可以处理世界上最好的情况。


1

通过使用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()" />


当通过按键方式(剪切,粘贴,删除选定的内容等)更改文本时,这种情况就消失了
Ian Boyd

@IanBoyd同意。为了使示例简单,我仅实现了按键验证。
vibs2006

0

尝试将事件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时,或者当鼠标选择了所有文本并按空格
Ian Boyd 2016年

我只是写了我的主意。您可以根据需要使用键码或其他方法来实现它。这只是我的主意。
拉玛·克里希纳

1
想法不是答案。SO的答案应该是简洁的解决方案,明确地回答OP的问题,以便每个人都可以受益。这显然不符合该标准。
CubicleSoft

0

有一种更好的方法可以做到这一点。使用concat方法。例

声明一个全局变量。这在角度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);
}

当关键是DeleteCtrl+ XCtrl+ VBackspace?或者,如果他们选择了一些文本,然后按A
伊恩·博伊德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.