¿La mejor manera de rastrear onchange a medida que escribe en input type = "text"?

449

En mi experiencia, el input type="text" onchangeevento generalmente ocurre solo después de que dejas ( blur) el control.

¿Hay alguna forma de obligar al navegador a activarse onchangecada vez textfieldque cambia el contenido? Si no, ¿cuál es la forma más elegante de rastrear esto "manualmente"?

El uso de onkey*eventos no es confiable, ya que puede hacer clic derecho en el campo y elegir Pegar, y esto cambiará el campo sin ninguna entrada de teclado.

¿Es setTimeoutla única manera? .. Feo :-)

Ilya Birman
fuente
@ ¿Hay alguna posibilidad de que pueda actualizar su respuesta aceptada para que la desactualizada no quede fijada en la parte superior?
Flimm

Respuestas:

271

Actualizar:

Ver otra respuesta (2015).


Respuesta original de 2009:

Entonces, ¿quieres que el onchangeevento se active al presionar teclas, desenfocar y pegar? Eso es magia

Si desea realizar un seguimiento de los cambios a medida que escriben, use "onkeydown". Si necesita atrapar operaciones de pegado con el mouse, use "onpaste"( IE , FF3 ) y "oninput"( FF, Opera, Chrome, Safari 1 ).

1 Roto por <textarea>en Safari. Usar en su textInputlugar

Creciente Fresco
fuente
22
onkeypressse debe utilizar en lugar de onkeydown. onkeydownse dispara cuando se hace clic en una tecla. Si un usuario mantiene presionada una tecla, el evento solo se disparará una vez para el primer personaje. onkeypressse activa cada vez que se agrega un carácter al campo de texto.
Fent
61
No es del todo mágico hacer onchangefuego sobre todas esas acciones. <input onchange="doSomething();" onkeypress="this.onchange();" onpaste="this.onchange();" oninput="this.onchange();">hará lo suficientemente bien para la mayoría.
Aroth
1
¿Qué pasa con la eliminación de texto en el cuadro de entrada con el mouse? No creo que esto funcione.
Jeevan
47
Con jquery 1.8.3, se ve así:$().on('change keydown paste input', function() {})
Narfanator
44
@AriWais: SÍ, omg, la mayor parte de SO debe quedar en desuso. Amigos, esta respuesta tiene 8 años . Desearía que hubiera un botón "obsoleto" para respuestas antiguas como esta, y la comunidad podría elegir la mejor.
Crescent Fresh el
658

En estos días escucha oninput. Se siente onchangesin la necesidad de perder el foco en el elemento. Es HTML5.

Es compatible con todos (incluso móviles), excepto IE8 y versiones inferiores. Para IE agregar onpropertychange. Lo uso así:

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>

Robert Siemer
fuente
63
En un mundo en constante cambio como lo son los estándares web, a veces la respuesta aceptada podría cambiar después de algunos años ... Esta es la nueva respuesta aceptada para mí.
Erick Petrucelli
1
El soporte para oninputincluso en IE9 es parcial ( caniuse.com/#feat=input-event ).
Kenston Choi
Puede valer la pena usarlo innerTexten lugar de innerHTMLpara que no se muestre ningún marcado
Jeevan Takhar
47

El siguiente código funciona bien para mí con Jquery 1.8.3

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

Javascript / JQuery:

$("#myId").on('change keydown paste input', function(){
      doSomething();
});
Amrit Pal Singh
fuente
11
La biblioteca jQuery no está etiquetada en la pregunta.
John Weisz
21
JQuery es una API de JavaScript, y me trajo aquí por una búsqueda de palabras clave con jQuery, no creo que vale la pena la creación de una nueva pregunta para cada qustion Javascript para la respuesta jquery ...
GaelDev
12
Si a las personas no se les permitiera sugerir el uso de bibliotecas en las respuestas, habría
MUCHAS
3
Dispara varias veces. Probablemente debido a cambios y keydown. La entrada probable solo es necesaria aquí.
mmm
1
no necesita el keydownporque duplicará el valor de la entrada, elimínelo.
Youssef Al Subaihi
43

Javascript es impredecible y divertido aquí.

  • onchange ocurre solo cuando desenfoca el cuadro de texto
  • onkeyup& onkeypressno siempre ocurre en el cambio de texto
  • onkeydown ocurre en el cambio de texto (pero no puede rastrear cortar y pegar con el clic del mouse)
  • onpaste& oncutocurre con la pulsación de teclas e incluso con el clic derecho del mouse.

Entonces, para rastrear el cambio en el cuadro de texto, necesitamos onkeydown, oncutyonpaste . En la devolución de llamada de este evento, si verifica el valor del cuadro de texto, no obtiene el valor actualizado ya que el valor se cambia después de la devolución de llamada. Entonces, una solución para esto es establecer una función de tiempo de espera con un tiempo de espera de 50 milisegundos (o puede ser menos) para rastrear el cambio.

Este es un truco sucio, pero esta es la única forma, como investigué.

Aquí hay un ejemplo. http://jsfiddle.net/2BfGC/12/

Sanket Sahu
fuente
44
oninputy textInputson los eventos la solución real para esto, pero no es compatible con todos los navegadores.
Sanket Sahu
Para el segundo punto, supongo que quiso decir onkeyupy onkeydown, que son similares. Ambos pueden capturar las teclas Ctrl, Alt, Shift y Meta. Para el tercer punto, supongo que te refieres onkeypress.
Daniel Stevens
12

onkeyupsucede después de escribir, por ejemplo, presiono tcuando levanto el dedo, la acción ocurre pero en keydownla acción sucede antes de que digito el caráctert

Espero que esto sea útil para alguien.

Por onkeyuplo tanto, es mejor para cuando desea enviar lo que acaba de escribir ahora.

Fernando André
fuente
8

Tenía un requisito similar (campo de texto de estilo twitter). Usado onkeyupy onchange. onchangeen realidad se encarga de las operaciones de pegado del mouse durante el enfoque perdido del campo.

[Actualización] En HTML5 o posterior, úselo oninputpara obtener actualizaciones de modificación de caracteres en tiempo real, como se explica en otras respuestas anteriores.

Mohnish
fuente
La entrada es útil si desea detectar cuándo el contenido de un área de texto, input: text, input: password o input: search element ha cambiado, porque el evento onchange en estos elementos se activa cuando el elemento pierde el foco, no inmediatamente después de la modificación .
hkasera
@hkasera Sí, con HTML5 oninputes el camino a seguir. Pero, cuando implementé, HTML5 no existía y teníamos IE 8 :(. Agradezco su actualización ya que proporciona información actualizada para los usuarios.
Mohnish
7

Si usa SOLO Internet Explorer, puede usar esto:

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

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

Espero que ayude.

RolandDeschain
fuente
8
Podría ser para un proyecto interno, supongo ... :)
eselk 12/12/12
94
¡Gracias a Dios que no vivo en esa casa! : D
Marco Matarazzi
13
Hace 10 años no habría nada gracioso en esta frase ... :(
Michał Tabor
44
para mí esto ayuda, estoy desarrollando un proyecto para algunos dispositivos móviles con un sistema operativo incorporado donde IE es el único navegador.
Anders M.
3
Si usa SOLO Internet Explorer - LOL. ¡Me alegró el día en 2016!
Jack Black
4

hay una solución bastante cercana (no arregles todas las formas de pegar) pero la mayoría de ellas:

Funciona tanto para entradas como para áreas de texto:

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

Hazlo así:

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

Como dije, no todas las formas de pegar activan un evento en todos los navegadores ... lo peor es que algunos no activan ningún evento en absoluto, pero los temporizadores son horribles para ser utilizados para tal.

Pero la mayoría de las formas de pegado se realizan con el teclado y / o el mouse, por lo que normalmente se activan onkeyup o onmouseup después de pegar, también se activa onkeyup al escribir en el teclado.

Asegúrese de que su código de verificación no tome mucho tiempo ... de lo contrario, el usuario tendrá una mala impresión.

Sí, el truco es disparar con la tecla y con el mouse ... pero cuidado, ¡ambos pueden ser disparados, así que ten en cuenta eso!

z666zz666z
fuente
4

Por favor, juzgue el próximo enfoque usando 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
});
Alex Uke
fuente
Yo uso de la misma manera
:)
Me doy cuenta de que esta no es la respuesta más nueva, pero ¿no desenfocar y volver a enfocar la entrada en cada tecla atornilla la ubicación del cursor si estuviera en cualquier lugar excepto el final de la entrada?
Michael Martin-Smucker
@ MichaelMartin-Smucker Creería que sí, pero aparentemente no: jsfiddle.net/gsss8c6L
Clonkex el
4

"input" funcionó para mí.

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

Usted podría utilizar los keydown, keyupy keypresseventos.

Gumbo
fuente
3

Para realizar un seguimiento de cada uno, intente este ejemplo y, antes de eso, reduzca completamente la velocidad de parpadeo del cursor a cero.

<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: el evento se genera al salir

onchange: el evento se genera al salir si se realiza algún cambio en inputtext

onkeydown: el evento se genera al presionar cualquier tecla (también para mantener pulsadas las teclas durante mucho tiempo)

onkeyup: el evento se genera en cualquier lanzamiento de tecla

onkeypress: igual que onkeydown (o onkeyup) pero no reaccionará para ctrl, backsace, alt other

Venkat
fuente
1

2018 aquí, esto es lo que hago:

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

Si puede señalar fallas en este enfoque, le agradecería.

a20
fuente
2
2019 aquí, y esto se disparará varias veces por cada pulsación de tecla. Para ver un ejemplo, vea aquí: jsfiddle.net/sp00n82/3r4691tq/5
sp00n
1

Método 1: agregue un detector de eventos para input:

element.addEventListener("input", myFunction);

 

Método 2: definir la oninputpropiedad con JavaScript:

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

 

Método 3: definir la oninputpropiedad con HTML:

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