A melhor maneira de rastrear uma troca conforme você digita em input type = "text"?

449

Na minha experiência, o input type="text" onchangeevento geralmente ocorre somente depois que você sai ( blur) do controle.

Existe uma maneira de forçar o navegador a disparar onchangesempre que o textfieldconteúdo for alterado? Caso contrário, qual é a maneira mais elegante de rastrear isso "manualmente"?

O uso de onkey*eventos não é confiável, pois você pode clicar com o botão direito do mouse no campo e escolher Colar, e isso mudará o campo sem nenhuma entrada do teclado.

É setTimeouto único caminho? .. Feio :-)

Ilya Birman
fonte
@ Existe alguma chance de você atualizar sua resposta aceita para que a desatualizada não seja fixada na parte superior?
Flimm

Respostas:

271

Atualizar:

Veja Outra resposta (2015).


Resposta original de 2009:

Então, você deseja que o onchangeevento seja acionado com pressionamento de tecla, desfoque e cole? Isso é mágico.

Se você deseja acompanhar as alterações à medida que digitam, use "onkeydown". Se você precisar interceptar as operações de colar com o mouse, use "onpaste"( IE , FF3 ) e "oninput"( FF, Opera, Chrome, Safari 1 ).

1 Quebrado para <textarea>no Safari. Use em textInputvez disso

Crescent Fresh
fonte
22
onkeypressdeve ser usado em vez de onkeydown. onkeydowné acionado quando uma tecla é pressionada. Se um usuário mantiver pressionada uma tecla, o evento será acionado apenas uma vez para o primeiro caractere. onkeypressé acionado sempre que um caractere é adicionado ao campo de texto.
fent 12/03/2012
61
Não é muito mágico fazer onchangefogo em todas essas ações. <input onchange="doSomething();" onkeypress="this.onchange();" onpaste="this.onchange();" oninput="this.onchange();">fará bem o suficiente para a maioria.
Aroth 25/04
1
Que tal excluir algum texto na caixa de entrada usando o mouse? Eu não acho que isso vai funcionar.
Jeevan
47
Com jquery 1.8.3, parece com:$().on('change keydown paste input', function() {})
Narfanator
4
@AriWais: SIM, omg a maior parte do SO deve ser preterida. Pessoal, esta resposta tem 8 anos . Eu gostaria que houvesse um botão "descontinuar" para respostas antigas como essa, e a comunidade pudesse escolher a melhor.
Crescent Fresh
658

Estes dias escutam oninput. Parece que onchangesem a necessidade de perder o foco no elemento. É HTML5.

É suportado por todos (inclusive dispositivos móveis), exceto o IE8 e abaixo. Para o IE, adicione onpropertychange. Eu uso assim:

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
fonte
63
Em um mundo em constante mudança, como os padrões da Web, às vezes a resposta aceita pode ser alterada após alguns anos ... Essa é a nova resposta aceita para mim.
precisa
1
O suporte para o oninputIE9, mesmo que parcial, é parcial ( caniuse.com/#feat=input-event ).
Kenston Choi
Pode valer a pena usar innerTextno lugar de, innerHTMLpara que nenhuma marcação seja renderizada
Jeevan Takhar 18/04
47

O código abaixo funciona bem para mim com o Jquery 1.8.3

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

Javascript / JQuery:

$("#myId").on('change keydown paste input', function(){
      doSomething();
});
Amrit Pal Singh
fonte
11
A biblioteca jQuery não está marcada na pergunta.
John Weisz
21
JQuery é uma API JavaScript, e eu fui trazido aqui por uma pesquisa com jQuery palavra-chave, eu não acho que vale a pena criar uma nova questão para cada qustion javascript para a resposta Jquery ...
GaelDev
12
Se as pessoas não tinham permissão para sugerir o uso de bibliotecas em respostas lá seria muito mais perguntas sem respostas sobre SO
dietbacon
3
Dispara várias vezes. Provavelmente devido a alterações e keydown. A entrada provável é necessária apenas aqui.
Mmm
1
você não precisa do keydownporque duplicará o valor da entrada, remova-o.
Youssef Al Subaihi
43

Javascript é imprevisível e engraçado aqui.

  • onchange ocorre apenas quando você desfoca a caixa de texto
  • onkeyup& onkeypressnem sempre ocorre na alteração de texto
  • onkeydown ocorre na alteração do texto (mas não pode acompanhar recortar e colar com um clique do mouse)
  • onpaste& oncutocorre com a tecla pressionada e até com o botão direito do mouse.

Então, para acompanhar a mudança na caixa de texto, precisamos onkeydown, oncute onpaste. No retorno de chamada desses eventos, se você verificar o valor da caixa de texto, não receberá o valor atualizado, pois o valor é alterado após o retorno de chamada. Portanto, uma solução para isso é definir uma função de tempo limite com um tempo limite de 50 mili-segundos (ou pode ser menor) para rastrear a alteração.

Este é um truque sujo, mas é o único caminho, como pesquisei.

Aqui está um exemplo. http://jsfiddle.net/2BfGC/12/

Sanket Sahu
fonte
4
oninpute textInputsão os eventos que são a solução real para isso, mas não são suportados por todos os navegadores.
Sanket Sahu
Para o segundo ponto, suponho que você quis dizer onkeyupe onkeydown, que são semelhantes. Ambos podem capturar as teclas Ctrl, Alt, Shift e Meta. Quanto ao terceiro ponto, suponho que você quis dizer onkeypress.
Daniel Stevens
12

onkeyupacontece depois que você digita, por exemplo, eu pressiono tquando levanto o dedo a ação acontece, mas keydowna ação acontece antes de digitar o caracteret

Espero que isso seja útil para alguém.

Então onkeyupé melhor para quando você deseja enviar o que você acabou de digitar agora.

Fernando André
fonte
8

Eu tinha um requisito semelhante (campo de texto no estilo twitter). Usado onkeyupe onchange. onchangena verdade, cuida das operações de colar do mouse durante o foco perdido do campo.

[Atualização] No HTML5 ou posterior, use oninputpara obter atualizações de modificação de caracteres em tempo real, conforme explicado em outras respostas acima.

Mohnish
fonte
O oninput é útil se você deseja detectar quando o conteúdo de um elemento da área de texto, entrada: texto, entrada: senha ou entrada: pesquisa foi alterado, porque o evento onchange nesses elementos é acionado quando o elemento perde o foco, não imediatamente após a modificação .
Hkasera 4/04
@hkasera Sim, com HTML5 oninputé o caminho a percorrer. Mas, quando eu implementada, HTML5 não existia e tivemos IE 8 :( Eu aprecio sua atualização, pois fornece informações up-to-date para os usuários..
Mohnish
7

Se você usa APENAS o Internet Explorer, pode usar o seguinte:

<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 ajude.

RolandDeschain
fonte
8
Poderia ser para um projeto in-house eu acho ... :)
eselk
94
Graças a Deus eu não moro naquela casa! : D
Marco Matarazzi
13
10 anos atrás, não haveria nada engraçado nessa frase .. :(
Michał Tabor
4
para mim isso ajuda, estou desenvolvendo um projeto para alguns dispositivos móveis com um SO incorporado, onde o IE é o único navegador.
Anders M.
3
Se você usar APENAS o Internet Explorer - LOL. Fiz o meu dia em 2016!
Jack Black
4

existe uma solução bastante próxima (não corrija todas as maneiras de colar), mas a maioria delas:

Ele funciona tanto para entradas quanto para áreas de texto:

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

Faça assim:

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

Como eu disse, nem todas as maneiras de colar acionam um evento em todos os navegadores ... o pior é que alguns não acionam nenhum evento, mas os Temporizadores são horríveis de serem usados ​​para isso.

Mas a maioria das maneiras de Colar é feita com teclado e / ou mouse; portanto, normalmente uma ativação ou ativação do mouse são acionadas após uma colagem, também a ativação da ativação ao digitar no teclado.

Verifique se o código de verificação não leva muito tempo ... caso contrário, o usuário fica com uma impressão ruim.

Sim, o truque é acionar a tecla e o mouse ... mas cuidado, ambos podem ser acionados, então lembre-se disso !!!

z666zz666z
fonte
4

Por favor, julgue a próxima abordagem usando o 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
fonte
Eu uso da mesma maneira
:)
Sei que essa não é a resposta mais recente, mas não desfocar e focar novamente a entrada em todas as teclas danificaria a posição do cursor se ela estivesse em algum lugar, exceto no final da entrada?
Michael Martin-Smucker
@ MichaelMartin-Smucker Você pensaria assim, mas aparentemente não: jsfiddle.net/gsss8c6L
Clonkex
4

"input" funcionou para mim.

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

Você pode usar as keydown, keyupe keypresseventos também.

quiabo
fonte
3

Para rastrear cada uma, tente este exemplo e reduza completamente a taxa de piscada do cursor para zero.

<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: evento gera na saída

onchange: evento gera na saída se houver alguma alteração feita no texto de entrada

onkeydown: o evento é gerado com qualquer pressionamento de tecla (também por muito tempo)

onkeyup: evento gera em qualquer liberação de chave

onkeypress: o mesmo que onkeydown (ou onkeyup), mas não reagirá com ctrl, backsace, alt outros

Venkat
fonte
1

2018 aqui, é isso que eu faço:

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

Se você puder apontar falhas nessa abordagem, ficaria grato.

a20
fonte
2
2019 aqui, e isso será acionado várias vezes para cada pressionamento de tecla. Por exemplo, veja aqui: jsfiddle.net/sp00n82/3r4691tq/5
sp00n
1

Método 1: Adicionar um ouvinte de evento para input:

element.addEventListener("input", myFunction);

 

Método 2: Defina a oninputpropriedade com JavaScript:

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

 

Método 3: Defina a oninputpropriedade com HTML:

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

O addEventListener de Robert Siemer não é suportado no IE8.

"As versões anteriores do IE suportavam um método EventTarget.attachEvent () equivalente e proprietário." https://developer.mozilla.org/it/docs/Web/API/Element/addEventListener

bpolelli
fonte
este é mais como um comentário a uma resposta existente do que uma nova resposta
slfan