Как получить текст текстового поля ввода во время onKeyPress?


87

Я пытаюсь получить текст в текстовом поле по мере того, как пользователь вводит его ( jsfiddle plays ):

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?

Бонусное чтение


1
Я считаю, что вам нужно добавить текущее нажатие клавиши к значению, прежде чем возвращать его; значение обновляется на keyUp, но данные доступны вам на keyDown.
Mathletics 06

Подъем ключа работает для меня, вам не нужен jQ для чего-то вроде этого, если вы не хотите добавлять раздувание
Ryan B

достаточно только onKeyUp для вашей задачи
dmytro

Обработка @mit Only onKeyUpне показывает изменения в текстовом поле по мере их появления.
Ian Boyd

если вы хотите удерживать любую клавишу и получить результат в текстовом поле, вы должны использовать как события onKeyPress, так и onKeyDown Скрипка Джонатана М. , но если вы хотите получить результат, не удерживая клавиши, достаточно только onKeyUp my fiddle .
dmytro

Ответы:


20

Обработка inputсобытия является последовательным решением: оно поддерживается для textareaи inputэлементов во всех современных браузерах , и это срабатывает точно , когда вам это нужно:

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 Boyd

@ Ян, рад помочь. Что вы имеете в виду под «обратной связью не соответствует введенному»? Нужна корректировка?
Jonathan M

теперь я вспомнил, что имел в виду! Обратная связь, о которой я говорю, будет окрашивать <input>элемент в красный или зеленый цвет или давать пользователю какой-то другой отзыв о том, что то, что они набрали, хорошо или плохо. В то время как ваш общепринятый ответ по- прежнему страдает от проблемы всегда быть «вне по одному» характер: . Только самый наблюдательный пользователь заметит обратную связь не соответствует тому , что они вошли» В действительности, так как от каждого конкретного одна ошибка возникает только во время повторения нажатия клавиши (т.е. они удерживают клавишу), никто (кроме меня) не заметит проблемы.
Ян Бойд,

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, который я сделал.
kapa

Вы правы, Chrome, похоже, не запускает события нажатия клавиш для Backspace; обновлено
Arnaud Le Blanc

@Ian, OP хочет, чтобы он обновлялся при удерживании клавиши? Не был уверен, было ли это требованием. Однако это решение не имеет такой функции.
Jonathan M

Для ясности: не запускать события нажатия клавиш для Backspace согласно Стандарту: «клавиша, которая производит символьное значение» - для других клавиш используйте «keydown» (до изменения, отменяемое) или «keyup» (после изменения)
sebilasse

5

держите его компактным.
Функция edValueKeyPress()вызывается каждый раз, когда вы нажимаете клавишу .
Вы также объявили и инициализировали некоторые переменные в этой функции, которые замедляют процесс и требуют больше ЦП и памяти.
Вы можете просто использовать этот код, полученный путем простой подстановки.

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. Не все нажатия клавиш передаются keydownиkeypress обработчики (например , Backspace и удалять ключи подавляются некоторыми браузерами).
  2. Обработка keydown- не лучшая идея. Бывают ситуации, когда нажатие клавиши НЕ приводит к нажатию клавиши!
  3. setTimeout() решения стиля задерживаются в веб-браузерах Google Chrome / Blink до тех пор, пока пользователь не перестанет печатать.
  4. События мыши и касания могут использоваться для выполнения таких действий, как вырезание, копирование и вставка. Эти события не будут запускать события клавиатуры.
  5. Браузер, в зависимости от метода ввода, может не доставлять уведомление об изменении элемента до тех пор, пока пользователь не уйдет от поля.

Более правильное решение справится с 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мероприятие?
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. Приведенный выше код подходит для первого, но потребует дополнительных усилий, чтобы учесть последнее и несколько других возможных ситуаций. См. Комментарий Яна Бойда ниже.]


1
@ bažmegakapa Или с помощью deleteклавиши, или если пользователь нажимает клавишу, которая не изменяет содержимое ( Ctrl+A), или если пользователь выбирает какой-то текст, а затем нажимает aдля замены подмножества. Идея прекрасная, Утканос, но хрупкая.
Ian Boyd

1
Согласовано. Я оставлю это, поскольку в этом есть некоторый пробег, но, как вы говорите, вам придется учитывать эти предостережения.
Митя

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.KeyCharэто Backspaceключ? Или Deleteключ? Или Ctrl+A?
Ян Бойд

Это даже JavaScript? void? object? методы первого верхнего регистра?
YakovL

1

Итак, у каждого мероприятия есть свои преимущества и недостатки. События onkeypressи onkeydownне получают последнее значение, иonkeypress не запускаются для непечатаемых символов в некоторых браузерах. ВonkeyupСобытие не определяет , когда клавиша нажата в течение нескольких символов.

Это немного взломано, но делать что-то вроде

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


Это разваливается, когда текст изменяется с помощью чего-то, что не является нажатием клавиши (вырезать, вставить, удалить выделенное и т. Д.)
Ян Бойд

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

Значение in abполучит последнее значение в поле ввода.


Извините, я заметил еще один пост с еще лучшим подходом на этой странице после того, как разместил это. Я не видел этого до публикации. Но я думаю, что мою концепцию проще понять.
Рама Кришна

Это довольно быстро разваливается, когда клавиша delete , backspace , Ctrl + X или Ctrl + V , или когда мышь выделяет весь текст, а я нажимаю пробел
Ян Бойд

Я просто написал свою идею. вы можете реализовать его в соответствии с вашими требованиями, используя коды клавиш или другие методы. Это всего лишь моя идея.
Рама Кришна

1
Идеи - это не ответы. Ответы на SO должны быть краткими решениями, которые окончательно отвечают на вопрос OP, чтобы каждый мог получить выгоду. Это явно не соответствует этим критериям.
CubicleSoft

0

Есть способ лучше. Используйте метод 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?
Ян Бойд,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.