ChatGPT解决这个技术问题 Extra ChatGPT

Best way to track onchange as-you-type in input type="text"?

In my experience, input type="text" onchange event usually occurs only after you leave (blur) the control.

Is there a way to force browser to trigger onchange every time textfield content changes? If not, what is the most elegant way to track this “manually”?

Using onkey* events is not reliable, since you can right-click the field and choose Paste, and this will change the field without any keyboard input.

Is setTimeout the only way?.. Ugly :-)


R
Robert Siemer

These days listen for oninput. It feels like onchange without the need to lose focus on the element. It is HTML5.

It’s supported by everyone (even mobile), except IE8 and below. For IE add onpropertychange. I use it like this:

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


Support for oninput even in IE9 though is partial (caniuse.com/#feat=input-event).
It may be worthwhile using innerText in place of innerHTML so that any markup isn't rendered
C
Community

Update:

See Another answer (2015).

Original 2009 Answer:

So, you want the onchange event to fire on keydown, blur, and paste? That's magic.

If you want to track changes as they type, use "onkeydown". If you need to trap paste operations with the mouse, use "onpaste" (IE, FF3) and "oninput" (FF, Opera, Chrome, Safari1).

1Broken for <textarea> on Safari. Use textInput instead


onkeypress should be used instead of onkeydown. onkeydown fires when a key is clicked down. If a user holds down a key, the event will only fire once for the first character. onkeypress fires whenever a char is added to the text field.
It's not quite magic to make onchange fire on all those actions. <input onchange="doSomething();" onkeypress="this.onchange();" onpaste="this.onchange();" oninput="this.onchange();"> will do well enough for most.
What about deleting some text in input box using mouse? I don't think this will work.
With jquery 1.8.3, looks like: $().on('change keydown paste input', function() {})
@AriWais: YES, omg most of SO should be deprecated. Folks this answer is 8 years old. I wish there was a "deprecate" button for old answers such as this one, and the community could choose the better one.
A
Arnaud

Below code works fine for me with Jquery 1.8.3

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

Javascript/JQuery:

$("#myId").on('change keydown paste input', function(){
      doSomething();
});

The jQuery library isn't tagged in the question.
Jquery is a Javascript api, and I was brought here by a search with Jquery keyword, I don't think it's worth creating a new question for each javascript qustion for the Jquery answer...
If people weren't allowed to suggest the use of libraries in answers there would be A LOT more unanswered questions on SO
Fires multiple times. Likely due to change and keydown. Likely input is only needed here.
you don't need the keydown because it will duplicate the value of the input, remove it.
S
Sanket Sahu

Javascript is unpredictable and funny here.

onchange occurs only when you blur the textbox

onkeyup & onkeypress doesn't always occur on text change

onkeydown occurs on text change (but cannot track cut & paste with mouse click)

onpaste & oncut occurs with keypress and even with the mouse right click.

So, to track the change in textbox, we need onkeydown, oncut and onpaste. In the callback of these event, if you check the value of the textbox then you don't get the updated value as the value is changed after the callback. So a solution for this is to set a timeout function with a timeout of 50 mili-seconds (or may be less) to track the change.

This is a dirty hack but this is the only way, as I researched.

Here is an example. http://jsfiddle.net/2BfGC/12/


oninput and textInput are the events which is the actual solution for this but, its not supported by all the browsers.
For the second bullet point I assume you meant onkeyup and onkeydown, which are similar. Both can capture Ctrl, Alt, Shift, and Meta keys. For the third bullet point I assume you meant onkeypress.
P
Patrick Hillert

I think in 2018 it's better to use the input event.

-

As the WHATWG Spec describes (https://html.spec.whatwg.org/multipage/indices.html#event-input-input):

Fired at controls when the user changes the value (see also the change event)

-

Here's an example of how to use it:

<input type="text" oninput="handleValueChange()">

This sounds right. Lots of developers seem to forget IMEs an voice dictation and swiping exist. Non game input, asking for a specific keycode is accessibility hostile and probe to breaking. Rule of thumb is, read text when focus is lost... Not before. If you want to be an IME, see what Octo.app did.
L
Lucky

onkeyup happens after you type for example I press t when I lift the finger the action happens but on keydown the action happens before I digit the character t

Hope this is helpful for someone.

So onkeyup is better for when you want to send what you just typed now.


M
Mohnish

I had a similar requirement (twitter style text field). Used onkeyup and onchange. onchange actually takes care of mouse paste operations during lost focus from the field.

[Update] In HTML5 or later, use oninput to get real time character modification updates, as explained in other answers above.


The oninput is useful if you want to detect when the contents of a textarea, input:text, input:password or input:search element have changed, because the onchange event on these elements fires when the element loses focus, not immediately after the modification.
@hkasera Yes, with HTML5 oninput is the way to go. But, when I implemented, HTML5 didn't exist and we had IE 8 :( . I appreciate your update as it provides up-to-date information for users.
K
Khushwant kodecha

Use oninput instead of onchange.

index.html

<html>
  <head>
    <title>title here</title>
    <script src="index.js"></script>
  </head>
  <body>
    <input oninput="onclickhandler(this)"></input>
  </body>
</html>

script.js

function onclickhandler(e) {
  console.log(e.value);
}


H
Harshal Patil

Please, judge next approach using JQuery:

HTML:

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

Javascript(JQuery):

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

$("#inputId").change(function() {
    // Do whatever you need to do on actual change of the value of the input field
});

I use the same way : )
I realize this isn't the newest answer, but wouldn't blurring and re-focusing the input on every keyup screw up the cursor placement if it was anywhere except the end of the input?
@MichaelMartin-Smucker You'd think so, but apparently not: jsfiddle.net/gsss8c6L
R
RolandDeschain

If you use ONLY Internet Explorer, you can use this:

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

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

Hope that helps.


Could be for an in-house project I guess... :)
for me this helps, I'm developping a project for some mobile with an embedded OS where IE is the only browser.
I use ONLY Internet Explorer and I have finally found my answer!
2021 and I wish I lived at that time
z
z666zz666z

there is a quite near solution (do not fix all Paste ways) but most of them:

It works for inputs as well as for textareas:

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

Do like this:

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

As i said, not all ways to Paste fire an event on all browsers... worst some do not fire any event at all, but Timers are horrible to be used for such.

But most of Paste ways are done with keyboard and/or mouse, so normally an onkeyup or onmouseup are fired after a paste, also onkeyup is fired when typing on keyboard.

Ensure yor check code does not take much time... otherwise user get a poor impresion.

Yes, the trick is to fire on key and on mouse... but beware both can be fired, so take in mind such!!!


J
JTG

"input" worked for me.

var searchBar  = document.getElementById("searchBar");
searchBar.addEventListener("input", PredictSearch, false);

V
Venkat

To track each try this example and before that completely reduce cursor blink rate to zero.

//try onkeydown,onkeyup,onkeypress

onblur : event generates on exit

onchange : event generates on exit if any changes made in inputtext

onkeydown: event generates on any key press (for key holding long times also)

onkeyup : event generates on any key release

onkeypress: same as onkeydown (or onkeyup) but won't react for ctrl,backsace,alt other


a
a20

2018 here, this is what I do:

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

If you can point out flaws in this approach, I would be grateful.


2019 here, and this will fire multiple times for each keypress. For an example, see here: jsfiddle.net/sp00n82/3r4691tq/5
G
Gumbo

You could use the keydown, keyup and keypress events as well.


P
Pikamander2

Method 1: Add an event listener for input:

element.addEventListener("input", myFunction);

Method 2: Define the oninput property with JavaScript:

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

Method 3: Define the oninput property with HTML:

<input type="text" oninput="myFunction();">