Як отримати текст вхідного текстового поля під час onKeyPress?


85

Я намагаюся отримати текст у текстовому полі під час введення користувачем ( 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?

Бонусна балачка

У DOM HTML є три події, пов’язані з "користувач набирає текст" :

  • 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.
Математика

Key up працює для мене, вам не потрібен jQ для чогось подібного, якщо ви не хочете додавати роздуття
Ryan B

досить тільки OnKeyUp для вашого завдання
дмитрий

@mit Тільки обробка onKeyUpне відображає зміни в текстовому полі, як вони відбуваються.
Ian Boyd

якщо ви хочете утримувати будь-яку клавішу і отримувати результат у текстовому полі, з цієї причини вам слід використовувати як скрипти подій onKeyPress, так і onKeyDown Джонатана М. , але якщо ви хочете отримати результат, не утримуючи клавіші, досить лише onKeyUp my fiddle .
dmytro

Відповіді:


19

Обробка 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

@Ian, радий допомогти. Що ви маєте на увазі під "зворотним зв'язком не відповідає тому, що вони ввели"? Чи потрібно коригування?
Джонатан М

я пам’ятаю, що я мав на увазі зараз! Зворотній зв'язок, про який я маю на увазі, полягає у забарвленні <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, здається, не запускає події натискання клавіш для зворотного простору; оновлено
Arnaud Le Blanc

@Ian, Операційна програма, яка бажає її оновлення, утримуючи клавішу? Не був надто впевнений, чи це була вимога. Однак це рішення не має такої функціональності.
Джонатан М

Щоб бути зрозумілим: не запускати події натискання клавіш для зворотного простору відповідає стандарту: "ключ, який видає значення символу" - для інших клавіш використовуйте "зменшення клавіші" (до зміни, скасування) або "клавіатуру" (після зміни)
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обробники (наприклад, деякі браузери пригнічують клавіші зворотного простору та видалення).
  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);
}

[EDIT - цей підхід за замовчуванням відключає натискання клавіш для таких речей, як пробіл, CTRL + A. Наведений вище код вміщує перших, але потребуватиме подальшого вдосконалення, щоб передбачити останню та кілька інших можливостей. Див. Коментар Яна Бойда нижче.]


1
@ bažmegakapa Або deleteклавішею, або якщо користувач натискає клавішу, яка не змінює вміст ( Ctrl+A), або якщо користувач виділяє якийсь текст, а потім натискає, aщоб замінити підмножину. Це чудова ідея, Утканос, але крихка.
Ян Бойд,

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отримає останнє значення у полі введення.


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

Це розвалюється досить швидко, коли клавіша видалення , повернення назад , Ctrl + X або Ctrl + V , або коли миша виділяє весь текст і я натискаю пробіл
Ян Бойд

Я щойно написав свою ідею. Ви можете реалізувати це згідно з вашими вимогами, використовуючи коди клавіш або інші методи. Це лише моя ідея.
Рама Крішна,

1
Ідеї ​​- це не відповіді. Відповіді на СО мають бути стислими рішеннями, які остаточно відповідають на питання ОП, щоб усі могли отримати користь. Це явно не відповідає цим критеріям.
CubicleSoft

0

Існує кращий спосіб зробити це. Використовуйте метод concat. Приклад

оголосити глобальну змінну. це добре працює на кутовому 10, просто передайте його у JavaScript Vanilla. Приклад:

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.