html <input type = “text” /> evento onchange não funciona

88

Estou tentando fazer alguma experiência. O que eu quero que aconteça é que toda vez que o usuário digitar algo na caixa de texto, isso seja exibido em uma caixa de diálogo. Usei a onchangepropriedade do evento para fazer isso acontecer, mas não funciona. Ainda preciso pressionar o botão Enviar para que funcione. Eu li sobre AJAX e estou pensando em aprender sobre isso. Ainda preciso do AJAX para fazê-lo funcionar ou o JavaScript é simples o suficiente? Por favor ajude.

index.php

<script type="text/javascript" src="javascript.js"> </script>

<form action="index.php" method="get">
 Integer 1: <input type="text" id="num1" name="num1" onchange="checkInput('num1');" /> <br />
 Integer 2: <input type="text" id="num2" name="num2" onchange="checkInput('num2');" /> <br />
 <input type="submit" value="Compute" />
</form>

javascript.js

function checkInput(textbox) {
 var textInput = document.getElementById(textbox).value;

 alert(textInput); 
}
Newbie Coder
fonte
4
você pode enviar "this" em vez do id, para não precisar chamar getElementById
remi bourgarel
Sim ... obrigado, eu fiz o que Ash Burlaczenko me disse ...
Newbie Coder
Com JQuery, boa solução proposta aqui: stackoverflow.com/a/8167009/2065594
Cyril Jacquart

Respostas:

127

onchangesó é acionado quando o controle está desfocado. Em onkeypressvez disso, tente .

Ignacio Vazquez-Abrams
fonte
19
Não funciona para detectar alterações após o usuário
colar
19
Isso só resolveu meu problema. Eu prefiro onkeyup, porém, pois obtém o novo valor em input('element.value')
stealthjong
4
Também noto que "keypress" não é gerado depois de pressionar backspace, pelo menos ao usar jquery. "keyup" é gerado após pressionar e soltar backspace. "input" resolve esse problema e também funciona para copiar e colar, e acho que essa é a solução adequada aqui (como o usuário "99 problemas - a sintaxe não é um" aponta abaixo).
Patrick Finnigan
4
'onkeypres', 'onkeyup', etc. não é uma solução quando se deseja chamar uma função apenas se o texto mudou ! Os eventos principais produzem um tráfego desnecessário neste caso. (É muito estranho que esta resposta tenha sido escolhida como uma solução, especialmente com tantos votos !! Eu não votei negativamente, porque não gosto de apenas votar negativamente nas respostas. Prefiro dar o (s) motivo (s) por que é não está OK - É mais útil!)
Apostolos
Para HTML ≥5 ou jQuery ≥1.7 existem outras soluções abaixo, que também tratam da colagem da área de transferência.
user202729
42

Use .on('input'...para monitorar cada alteração em uma entrada (colar, digitar, etc) do jQuery 1.7 e superior.

Para entradas estáticas e dinâmicas:

$(document).on('input', '.my-class', function(){
    alert('Input changed');
});

Apenas para entradas estáticas:

$('.my-class').on('input', function(){
    alert('Input changed');
});

JSFiddle com exemplo estático / dinâmico: https://jsfiddle.net/op0zqrgy/7/

rybo111
fonte
Isso funcionou perfeitamente para mim - obrigado. Nota para os outros - não se esqueça de realmente executar o código acima em seu onLoad ou algo assim para 'começar' o monitoramento.
Robert Penridge
Tarde demais para um comentário, mas ... Por que você sugere usar jQuery se o usuário que está respondendo mostra JavaScript simples?
Andrés Morales
@ AndrésMorales É uma biblioteca comum à qual muitos aplicativos têm acesso imediato e é simples de adicionar aos que não têm. Obviamente, essa resposta não se aplica aos aplicativos que não podem (ou optam por não) usar jQuery.
rybo111
@ rybo111 Exatamente! jQuery é uma biblioteca comum e amplamente usada, mas liga diretamente em meu cérebro à questão do meme sobre "somar dois números usando JavaScript" e a resposta mais votada sobre como usar jQuery para fazer isso. Não é o caso, mas muitas pessoas não conseguem separar JavaScript e jQuery.
Andrés Morales
@ AndrésMorales Observe que minha resposta cobre "colar, digitar, etc". Lembro-me da solução jQuery ser conveniente quando respondi a esta pergunta (7 anos atrás!).
rybo111
30

Verificar se há pressionamentos de tecla é apenas uma solução parcial, porque é possível alterar o conteúdo de um campo de entrada usando cliques do mouse. Se você clicar com o botão direito em um campo de texto, terá opções de recortar e colar que podem ser usadas para alterar o valor sem pressionar uma tecla. Da mesma forma, se o preenchimento automático estiver habilitado, você pode clicar com o botão esquerdo em um campo e obter uma lista suspensa do texto inserido anteriormente, e pode selecionar entre suas opções usando um clique do mouse. A captura de pressionamento de tecla não detectará nenhum desses tipos de alterações.

Infelizmente, não há evento "onchange" que relata mudanças imediatamente, pelo menos até onde eu sei. Mas existe uma solução que funciona para todos os casos: configure um evento de temporização usando setInterval ().

Digamos que seu campo de entrada tenha um id e nome de "cidade":

<input type="text" name="city" id="city" />

Possui uma variável global chamada "cidade":

var city = "";

Adicione isto à inicialização da sua página:

setInterval(lookForCityChange, 100);

Em seguida, defina uma função lookForCityChange ():

function lookForCityChange()
{
    var newCity = document.getElementById("city").value;
    if (newCity != city) {
        city = newCity;
        doSomething(city);     // do whatever you need to do
    }
}

Neste exemplo, o valor de "cidade" é verificado a cada 100 milissegundos, que você pode ajustar de acordo com suas necessidades. Se desejar, use uma função anônima em vez de definir lookForCityChange (). Esteja ciente de que seu código ou mesmo o navegador pode fornecer um valor inicial para o campo de entrada, portanto, você pode ser notificado sobre uma "mudança" antes que o usuário faça qualquer coisa; ajuste seu código conforme necessário.

Se a ideia de um evento de temporização disparando a cada décimo de segundo parecer deselegante, você pode iniciar o temporizador quando o campo de entrada receber o foco e encerrá-lo (com clearInterval ()) em um desfoque. Não acho que seja possível alterar o valor de um campo de entrada sem que ele receba o foco, portanto, ligar e desligar o cronômetro dessa forma deve ser seguro.

Libélula
fonte
1
Se não for possível alterar o valor de um campo de entrada sem que ele obtenha o foco e um desfoque ocorre quando um elemento perde o foco, por que não apenas procurar por alterações no onblur?
Pakman
Você deseja agir quando o campo de entrada muda ou quando perde o foco após uma mudança? Se você quiser agir imediatamente, não pode esperar pelo onblur.
Dragonfly
@Pakman Essa é uma solução decente em alguns casos. Mas se você quiser fazer pesquisa enquanto você digita - um recurso muito bom, IMO (por que o usuário deveria procurar por coisas quando o computador pode fazer isso muito mais rápido e sem ficar entediado?) - ou qualquer outra coisa realmente precisa acontecer quando o texto muda, por que você não deveria?
The Dag de
Tão triste que chegue a esse ponto.
Chuck Batson de
1
@ChuckBatson Esta resposta é de 2012. Notei que você postou seu comentário em 2016. Veja minha resposta se você estiver usando jQuery, é incrivelmente fácil agora.
rybo111
26

HTML5 define um oninputevento para capturar todas as mudanças diretas. funciona para mim.

Soufiane ELH
fonte
1
funciona com o controle giratório type = "number" também (com o qual o onkeypress não funciona).
Bob
13

onchange só ocorre quando a mudança no elemento de entrada é confirmada pelo usuário, na maioria das vezes é quando o elemento perde o foco.

se você deseja que sua função seja acionada toda vez que o valor do elemento mudar, você deve usar o oninputevento - isso é melhor do que os eventos chave para cima / para baixo, pois o valor pode ser alterado com o mouse do usuário, ou seja, colado ou preenchido automaticamente, etc.

Leia mais sobre o evento de mudança aqui

Leia mais sobre o evento de entrada aqui

99 problemas - a sintaxe não é uma
fonte
11

use os seguintes eventos em vez de "onchange"

- onkeyup(event)
- onkeydown(event)
- onkeypress(event)
metaforce
fonte
6

Em primeiro lugar, o que 'não funciona'? Você não vê o alerta?

Além disso, seu código pode ser simplificado para este

<input type="text" id="num1" name="num1" onkeydown="checkInput(this);" /> <br />

function checkInput(obj) {
    alert(obj.value); 
}
Ash Burlaczenko
fonte
2

Encontrei problemas em que o Safari não estava disparando eventos "onchange" em um campo de entrada de texto. Usei um evento de "mudança" do jQuery 1.7.2 e também não funcionou. Acabei usando o evento textchange do ZURB. Funciona com eventos do mouse e pode disparar sem sair do campo:
http://www.zurb.com/playground/jquery-text-change-custom-event

$('.inputClassToBind').bind('textchange', function (event, previousText) {
    alert($(this).attr('id'));
});
James Moberg
fonte
2

Alguns comentários de que IMO são importantes:

  • os elementos de entrada não emitem evento de 'mudança' até que a ação do USUÁRIO ENTER ou desfoque aguarde É o comportamento correto .

  • O evento que você deseja usar é "input"(" oninput "). Aqui está bem demonstrado a diferença entre os dois: https://javascript.info/events-change-input

  • Os dois eventos sinalizam dois gestos / momentos do usuário diferentes (evento "entrada" significa que o usuário está escrevendo ou navegando nas opções da lista de seleção, mas ainda não confirmou a alteração. "Alterar" significa que o usuário alterou o valor (com um enter ou desfoque nosso)

  • Ouvir eventos importantes como muitos aqui recomendados é uma prática ruim neste caso. (como pessoas modificando o comportamento padrão de ENTER nas entradas) ...

  • jQuery não tem nada a ver com isso. Isso tudo está no padrão HTML.

  • Se você tiver problemas para entender PORQUE este é o comportamento correto, talvez seja útil, como experiência, use seu editor de texto ou navegador sem um mouse / pad, apenas um teclado.

Meus dois centavos.

cancerbero
fonte
1

onkeyup funcionou para mim. onkeypress não dispara ao pressionar espaço para trás.

Bishnu Paudel
fonte
e quando um valor é colado? Eu uso "onpaste" para acionar o evento também
Louis
1

É melhor usar onchange(event)com <select>. Com <input>você pode usar o evento abaixo:

- onkeyup(event)
- onkeydown(event)
- onkeypress(event)
Bhavin Patel
fonte
-3

tente onpropertychange. ele só funciona para o IE.

jack jiao
fonte
6
Por que alguém iria querer considerar uma propriedade que só funciona em um BROWSER OBSOLETO que foi abandonado por seu desenvolvedor? Votar negativamente.
Sod Todo-Poderoso,