Лучший способ отследить onchange по мере ввода в тип ввода = «текст»?

449

По моему опыту, input type="text" onchangeсобытие обычно происходит только после вашего ухода (blur ) элемент управления.

Есть ли способ заставить браузер запускать onchange каждый раз при textfieldизменении содержимого? Если нет, то какой самый элегантный способ отследить это «вручную»?

С помощью onkey* событий не является надежным, так как вы можете щелкнуть правой кнопкой мыши поле и выбрать Вставить, и это изменит поле без ввода с клавиатуры.

Это setTimeoutединственный способ? .. Гадкий :-)

Илья Бирман
источник
@ Есть ли шанс, что вы сможете обновить свой принятый ответ, чтобы устаревший ответ не был прикреплен к началу?
Флим

Ответы:

271

Обновить:

Смотрите другой ответ (2015).


Оригинал 2009 Ответ:

Итак, вы хотите, чтобы onchangeсобытие запускалось при нажатии клавиш, размытии и вставке? Это волшебство.

Если вы хотите отслеживать изменения по мере их ввода, используйте "onkeydown". Если вам нужно перехватить операции вставки с помощью мыши, используйте "onpaste"( IE , FF3 ) и "oninput"( FF, Opera, Chrome, Safari 1 ).

1 Сломан для <textarea>сафари. Используйте textInputвместо

Свежий полумесяц
источник
22
onkeypressследует использовать вместо onkeydown. onkeydownсрабатывает при нажатии клавиши. Если пользователь удерживает клавишу, событие будет запущено только один раз для первого символа. onkeypressсрабатывает всякий раз, когда символ добавляется в текстовое поле.
отправлено
61
Это не совсем волшебство, чтобы onchangeподжечь все эти действия. <input onchange="doSomething();" onkeypress="this.onchange();" onpaste="this.onchange();" oninput="this.onchange();">будет достаточно хорошо для большинства.
'11
1
Как насчет удаления текста в поле ввода с помощью мыши? Я не думаю, что это сработает.
Дживан
47
С jquery 1.8.3, выглядит так:$().on('change keydown paste input', function() {})
Нарфанатор
4
@ AriWais: ДА, боже мой, большая часть SO должна быть устаревшей. Людям этот ответ 8 лет . Хотелось бы, чтобы для старых ответов, таких как этот, была кнопка «отказаться», и сообщество могло бы выбрать лучший.
Crescent Fresh
658

В эти дни слушай oninput. Такое ощущение, что onchangeнет необходимости терять фокус на элементе. Это HTML5.

Он поддерживается всеми (даже мобильными), кроме IE8 и ниже. Для IE добавить onpropertychange. Я использую это так:

const source = document.getElementById('source');
const result = document.getElementById('result');

const inputHandler = function(e) {
  result.innerHTML = e.target.value;
}

source.addEventListener('input', inputHandler);
source.addEventListener('propertychange', inputHandler); // for IE8
// Firefox/Edge18-/IE9+ don’t fire on <select><option>
// source.addEventListener('change', inputHandler); 
<input id="source">
<div id="result"></div>

Роберт Симер
источник
63
В постоянно меняющемся мире, таком как веб-стандарты, иногда принятый ответ может быть изменен через несколько лет ... Это новый принятый ответ для меня.
Эрик Петручелли
1
Поддержка oninputдаже в IE9 хотя и частичная ( caniuse.com/#feat=input-event ).
Кенстон Чой
Возможно, стоит использовать innerTextвместо innerHTMLтак, чтобы любая разметка не отображалась
Дживан Тахар
47

Ниже код отлично работает для меня с Jquery 1.8.3

HTML: <input type="text" id="myId" />

Javascript / JQuery:

$("#myId").on('change keydown paste input', function(){
      doSomething();
});
Амрит Пал Сингх
источник
11
Jquery библиотека не помечена в этом вопросе.
Джон Вайс
21
Jquery - это API-интерфейс Javascript, и меня привел поиск по ключевому слову Jquery, я не думаю, что стоит создавать новый вопрос для каждого java-сценария для ответа на
Jquery
12
Если бы людям не разрешали предлагать использование библиотек в ответах, было бы
ОЧЕНЬ
3
Пожары несколько раз. Скорее всего, из-за изменений и нажатия клавиш. Вероятный вклад нужен только здесь.
ммм
1
вам не нужно, keydownпотому что он будет дублировать значение ввода, удалите его.
Юсеф Аль Субайхи
43

Javascript здесь непредсказуем и забавен.

  • onchange происходит только при размытии текстового поля
  • onkeyup& onkeypressне всегда происходит при изменении текста
  • onkeydown происходит при изменении текста (но не может отслеживать вырезать и вставить с помощью мыши)
  • onpaste& oncutпроисходит при нажатии клавиш и даже при щелчке правой кнопкой мыши.

Итак, чтобы отслеживать изменения в текстовом поле, нам нужно onkeydown, oncutи onpaste. При обратном вызове этого события, если вы проверите значение текстового поля, вы не получите обновленное значение, так как значение изменяется после обратного вызова. Таким образом, решение для этого состоит в том, чтобы установить функцию тайм-аута с тайм-аутом 50 миллисекунд (или может быть меньше), чтобы отслеживать изменения.

Это грязный взлом, но это единственный способ, как я исследовал.

Вот пример. http://jsfiddle.net/2BfGC/12/

Санкет саху
источник
4
oninputи textInputявляются событиями, которые являются фактическим решением для этого, но не поддерживаются всеми браузерами.
Санкет Саху
Для второго пункта пули я предполагаю, что вы имели в виду onkeyupи onkeydown, которые похожи. Оба могут захватывать клавиши Ctrl, Alt, Shift и Meta. Для третьего пункта пули я предполагаю, что вы имели в виду onkeypress.
Даниэль Стивенс
12

onkeyupпроисходит после того, как вы наберете, например, я нажимаю, tкогда я поднимаю палец, действие происходит, но на keydownдействие происходит, прежде чем я оцифровываю символt

Надеюсь, это полезно для кого-то.

Так onkeyupчто лучше, когда вы хотите отправить то, что вы только что набрали.

Фернандо Андре
источник
8

У меня было похожее требование (текстовое поле в стиле твиттера). Используется onkeyupи onchange. onchangeфактически заботится об операциях вставки мыши во время потери фокуса с поля.

[Обновление] В HTML5 или новее используйте oninputдля получения обновлений модификации символов в реальном времени, как объяснено в других ответах выше.

Mohnish
источник
Параметр oninput полезен, если вы хотите определить, когда содержимое элемента textarea, input: text, input: password или input: search изменилось, поскольку событие onchange в этих элементах запускается, когда элемент теряет фокус, а не сразу после изменения. ,
hkasera
@hkasera Да, с HTML5 oninputэто путь. Но когда я реализовал, HTML5 не существовало, и у нас был IE 8 :(. Я ценю ваше обновление, поскольку оно предоставляет актуальную информацию для пользователей.
Mohnish
8

Я думаю, что в 2018 году лучше использовать inputсобытие.

-

Как описывает спецификация WHATWG ( https://html.spec.whatwg.org/multipage/indices.html#event-input-input ):

Срабатывает в элементах управления, когда пользователь изменяет значение (см. Также событие изменения )

-

Вот пример того, как его использовать:

<input type="text" oninput="handleValueChange()">
Патрик Хиллерт
источник
7

Если вы используете ТОЛЬКО Internet Explorer, вы можете использовать это:

<input type="text" id="myID" onpropertychange="TextChange(this)" />

<script type="text/javascript">
    function TextChange(tBox) {
        if(event.propertyName=='value') {
            //your code here
        }
    }
</script>

Надеюсь, это поможет.

Роланд Дискейн
источник
8
Может быть, для внутреннего проекта, я думаю ... :)
eselk
94
Слава богу, я не живу в этом доме! : D
Марко Матарацци
13
10 лет назад в этом предложении не было бы ничего смешного .. :(
Михал Табор
4
для меня это помогает, я разрабатываю проект для некоторых мобильных устройств со встроенной ОС, где IE является единственным браузером.
Андерс М.
3
Если вы используете ТОЛЬКО Internet Explorer - LOL. Сделал мой день в 2016 году!
Джек Блэк,
4

Существует довольно близкое решение (не исправляйте все способы вставки), но большинство из них:

Это работает для входов, а также для текстовых областей:

<input type="text" ... >
<textarea ... >...</textarea>

Делай так:

<input type="text" ... onkeyup="JavaScript: ControlChanges()" onmouseup="JavaScript: ControlChanges()" >
<textarea ... onkeyup="JavaScript: ControlChanges()" onmouseup="JavaScript: ControlChanges()" >...</textarea>

Как я уже сказал, не все способы вставить событие во все браузеры ... в худшем случае некоторые не запускают события вообще, но таймеры ужасно использовать для таких целей.

Но большинство способов вставки выполняется с помощью клавиатуры и / или мыши, поэтому обычно onkeyup или onmouseup запускаются после вставки, также onkeyup запускается при вводе с клавиатуры.

Убедитесь, что ваш контрольный код не займет много времени ... в противном случае пользователь получит плохое впечатление.

Да, хитрость в том, чтобы стрелять по клавишам и мышам ... но будьте осторожны, оба могут быть запущены, так что имейте в виду, что такое !!!

z666zz666z
источник
4

Пожалуйста, оцените следующий подход, используя JQuery:

HTML:

<input type="text" id="inputId" />

Javascript (JQuery):

$("#inputId").keyup(function(){
        $("#inputId").blur();
        $("#inputId").focus();
});

$("#inputId").change(function(){
        //do whatever you need to do on actual change of the value of the input field
});
Алекс Уке
источник
Я использую так же
:)
Я понимаю, что это не самый новый ответ, но разве размытие и перефокусировка ввода на каждой клавише не испортило бы расположение курсора, если бы оно было где-нибудь кроме конца ввода?
Майкл Мартин-
@ MichaelMartin-Smucker Вы бы так подумали, но, видимо, нет: jsfiddle.net/gsss8c6L
Clonkex
4

«вход» работал для меня.

var searchBar  = document.getElementById("searchBar");
searchBar.addEventListener("input", PredictSearch, false);
Сэм
источник
3

Вы могли бы использовать keydown, keyupи keypressсобытия , а также.

гумбо
источник
3

Для отслеживания каждого попробуйте этот пример, а перед этим полностью уменьшите частоту мигания курсора до нуля.

<body>
//try onkeydown,onkeyup,onkeypress
<input type="text" onkeypress="myFunction(this.value)">
<span> </span>
<script>
function myFunction(val) {
//alert(val);
var mySpan = document.getElementsByTagName("span")[0].innerHTML;
mySpan += val+"<br>";
document.getElementsByTagName("span")[0].innerHTML = mySpan;
}
</script>

</body>

onblur: событие генерируется при выходе

onchange: событие генерируется при выходе, если в inputtext вносятся какие-либо изменения

onkeydown: событие генерируется при любом нажатии клавиши (также для долгого удержания клавиши)

onkeyup: событие генерируется при любом отпускании ключа

onkeypress: то же, что onkeydown (или onkeyup), но не будет реагировать на ctrl, backsace, alt other

Venkat
источник
1

2018 здесь, это то, что я делаю:

$(inputs).on('change keydown paste input propertychange click keyup blur',handler);

Если вы можете указать на недостатки в этом подходе, я был бы признателен.

a20
источник
2
2019 здесь, и это будет срабатывать несколько раз для каждого нажатия клавиши. Для примера, смотрите здесь: jsfiddle.net/sp00n82/3r4691tq/5
sp00n
1

Метод 1: Добавить прослушиватель событий для input:

element.addEventListener("input", myFunction);

 

Способ 2. Определите oninputсвойство с помощью JavaScript:

element.oninput = function()
{
    myFunction();
};

 

Способ 3: определить oninputсвойство с помощью HTML:

<input type="text" oninput="myFunction();">
Pikamander2
источник
0

Роберт Симер addEventListener не поддерживается в IE8.

«Старые версии IE поддерживали эквивалентный проприетарный метод EventTarget.attachEvent ()». https://developer.mozilla.org/it/docs/Web/API/Element/addEventListener

bpolelli
источник
это больше похоже на комментарий к существующему ответу, чем на новый ответ
slfan