O evento de alteração da caixa de texto do jQuery não é acionado até que a caixa de texto perca o foco?

133

Descobri que o evento de alteração do jQuery em uma caixa de texto não é acionado até clicar fora da caixa de texto.

HTML:

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

JS:

$("#textbox").change(function() {alert("Change detected!");});

Veja a demonstração no JSFiddle

Meu aplicativo requer que o evento seja acionado em cada alteração de caractere na caixa de texto. Eu até tentei usar o keyup ...

$("#textbox").keyup(function() {alert("Keyup detected!");});

... mas é um fato conhecido que o evento keyup não é acionado com o botão direito do mouse e colar.

Alguma solução alternativa? Os dois ouvintes vão causar problemas?

SNag
fonte
^^ Isso. Você pode ter quantos manipuladores de eventos desejar.
Reintegrar Monica Cellio

Respostas:

298

A ligação a ambos os eventos é a maneira típica de fazer isso. Você também pode vincular ao evento de colar.

Você pode vincular a vários eventos como este:

$("#textbox").on('change keyup paste', function() {
    console.log('I am pretty sure the text box changed');
});

Se você quisesse ser pedante sobre isso, também deve vincular a mouseup para arrastar o texto e adicionar uma lastValuevariável para garantir que o texto realmente seja alterado:

var lastValue = '';
$("#textbox").on('change keyup paste mouseup', function() {
    if ($(this).val() != lastValue) {
        lastValue = $(this).val();
        console.log('The text box really changed this time');
    }
});

E se você quer ser super duperpedante, deve usar um temporizador de intervalo para atender ao preenchimento automático, plugins, etc:

var lastValue = '';
setInterval(function() {
    if ($("#textbox").val() != lastValue) {
        lastValue = $("#textbox").val();
        console.log('I am definitely sure the text box realy realy changed this time');
    }
}, 500);
Petah
fonte
9
Finalmente alguém leu a pergunta e respondeu a coisa toda!
Reponha Monica Cellio
4
.on('change keyup paste', function() {...}realmente dispara várias vezes! Se eu digitar um caractere e depois clicar fora, os eventos 'change' e 'keyup' serão acionados, levando a função a ser executada várias vezes! Se eu clicar com o botão direito do mouse em colar e depois clicar fora, 'alterar' e 'colar' serão acionadas. Heck! Ao usar Ctrl + V para colar e clicar fora, ele é acionado três vezes!
Senão
1
@ SNAG sim, então você também deve adicionar uma verificação usando uma lastValuevariável para garantir que ela realmente foi alterada.
Petah
1
+1. No entanto, a vinculação à 'mudança' é necessária aqui? Não está claro para mim o caso que resolveria que já não teria sido tratado no momento em que (alteração) foi acionado.
Madbreaks
1
O evento paste é disparado antes do texto é realmente colado
developerbmw
85

Nos navegadores modernos, você pode usar o inputevento :

DEMO

$("#textbox").on('input',function() {alert("Change detected!");});
A. Wolff
fonte
1
Legal - eu não estava ciente disso. É uma coisa HTML5?
Reintegrar Monica Cellio
4
Eu adoraria aceitar esta resposta, mas, como você disse, esta é uma solução para navegadores modernos. Meu aplicativo da web é direcionado a usuários que ainda usam o IE8, e isso não funciona no IE8. :( O que posso dizer .. :(
SNag
Não dispara se, por exemplo, selecione todo o texto e bater tecla delete
jjxtra
4
$(this).bind('input propertychange', function() {
        //your code here
    });

Isso funciona para digitar, colar, clicar com o botão direito do mouse, etc.

Tony Dong
fonte
1
Essa parece ser a melhor solução, pois não dispara vários eventos se você fizer algo como pressionar a seta para cima em um campo numérico.
Justin Justin
Solução simples e eficiente
Abdulhameed 09/01
4
if you write anything in your textbox, the event gets fired.
code as follows :

HTML:

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

JS:

<script type="text/javascript">
  $(function () {
      $("#textbox").bind('input', function() {
      alert("letter entered");
      });
   });
</script>
Milão
fonte
2

Tente o seguinte:

$("#textbox").bind('paste',function() {alert("Change detected!");});

Veja a demonstração no JSFiddle .

Dhaval Marthak
fonte
Como a pergunta está colada, ela não funciona. evento não é acionado com o botão direito do mouse e colar.
Dhaval Marthak
E o que isso tem a ver com o uso de bind()?
Reintegrar Monica Cellio
ele disse que o evento keyup não é disparado quando o botão direito + colar nele, então keyupe change()tem seu próprio comportamento típico de modo id ele quer executar evento, em seguida, pastepode ser a opção
Dhaval Marthak
Claro, mas isso ainda não responde por que usar em bindvez de on.
Reintegrar Monica Cellio
0

Experimente o código abaixo:

$("#textbox").on('change keypress paste', function() {
  console.log("Handler for .keypress() called.");
});
Venkat.R
fonte
Como isso captura a colagem com o mouse, conforme mencionado na pergunta?
Reintegrar Monica Cellio
keypress é adequado desde que ele disse queevent to be fired on every character change in the textbox
Venkat.R
Se você quiser ler toda a pergunta que você veria ele também disse,"...but it's a known fact that the keyup event isn't fired on right-click-and-paste."
Reintegrar Monica Cellio
0

Ler seus comentários me levou a uma correção suja. Sei que não é o caminho certo, mas pode ser uma solução alternativa.

$(function() {
    $( "#inputFieldId" ).autocomplete({
        source: function( event, ui ) {
            alert("do your functions here");
            return false;
        }
    });
});
Kevin Sebastian Fernandez
fonte