evento onchange para tipo de entrada = “número”

86

Como posso lidar com um onchange for <input type="number" id="n" value="5" step=".5" />? Não consigo fazer um keyupou keydown, porque o usuário pode apenas usar as setas para alterar o valor. Eu gostaria de lidar com isso sempre que houver mudança, não apenas no desfoque, o que acho que o .change()evento muda . Alguma ideia?

Ian Davis
fonte
2
Você percebeu que o tipo de entrada não é compatível com o IE ou Firefox?
AlienWebguy
Agora é compatível com Firefox
ElephantHunter
2
caniuse.com/#feat=input-number Sim, estou comentando uma pergunta de seis anos atrás.
Pete

Respostas:

135

Use mouseup e keyup

$(":input").bind('keyup mouseup', function () {
    alert("changed");            
});

http://jsfiddle.net/XezmB/2/

JohnColvin
fonte
4
Isso alertará mesmo se o valor não tiver mudado (basta clicar em qualquer lugar no input).
James Allardice
Sim vai. Se isso for um problema, você deve acompanhar o valor da entrada em uma variável global ou em um elemento de dados na entrada. Quando o evento mouseup chamar sua função, compare esse valor com o valor atual da entrada. Só faça algo se o valor tiver mudado.
JohnColvin
3
Isso não funciona se o valor for alterado pela rolagem do mouse acima do elemento.
Ondrej Machulda de
7
Adicione o evento "mousewheel" para oferecer suporte a alterações por rolagem.
Martijn
4
Se o usuário mantiver uma tecla de seta pressionada para alterar o valor, isso não disparará até que a tecla de seta seja liberada. Em inputvez disso, usar (como sugerido em outra resposta) parece funcionar melhor.
Josh Kelley
76

O oninputevento ( .bind('input', fn)) cobre todas as alterações de pressionamentos de tecla a cliques em setas e colagem de teclado / mouse, mas não é compatível com o IE <9.

jQuery(function($) {
  $('#mirror').text($('#alice').val());

  $('#alice').on('input', function() {
    $('#mirror').text($('#alice').val());
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input id="alice" type="number" step="any" value="99">

<p id="mirror"></p>

Flo
fonte
10

http://jsfiddle.net/XezmB/8/

$(":input").bind('keyup change click', function (e) {
    if (! $(this).data("previousValue") || 
           $(this).data("previousValue") != $(this).val()
       )
   {
        console.log("changed");           
        $(this).data("previousValue", $(this).val());
   }

});


$(":input").each(function () {
    $(this).data("previousValue", $(this).val());
});​

Este é um pequeno gueto, mas desta forma você pode usar o evento "click" para capturar o evento que é executado quando você usa o mouse para aumentar / diminuir através das pequenas setas na entrada. Você pode ver como criei uma pequena rotina manual de "verificação de alteração" que garante que sua lógica não seja acionada a menos que o valor realmente seja alterado (para evitar falsos positivos de cliques simples no campo).

Jake Feasel
fonte
6

Para detectar quando o mouse ou a tecla são pressionados, você também pode escrever:

$(document).on('keyup mouseup', '#your-id', function() {                                                                                                                     
  console.log('changed');
});
Kingsley Ijomah
fonte
3
$(':input').bind('click keyup', function(){
    // do stuff
});

Demo: http://jsfiddle.net/X8cV3/

AlienWebguy
fonte
Isso ainda será executado se o valor não tiver mudado (basta clicar em qualquer lugar no input).
James Allardice
Isso é verdade, mas uma vez que ele captura o evento, ele pode determinar se o valor mudou ou não.
AlienWebguy
3

Como $("input[type='number']")não funciona no IE, devemos usar um nome de classe ou id, por exemplo $('.input_quantity'),.

E não use o .bind()método. O .on()método é o método preferido para anexar manipuladores de eventos a um documento.

Então, minha versão é:

HTML

<input type="number" value="5" step=".5" min="1" max="999" id="txt_quantity" name="txt_quantity" class="input_quantity">

jQuery

<script>
$(document).ready(function(){
    $('.input_quantity').on('change keyup', function() {
        console.log('nice');
    }); 
});
</script>
SandroMarques
fonte
1

Pode haver uma solução melhor, mas é o que me veio à mente:

var value = $("#yourInput").val();
$("#yourInput").on('keyup change click', function () {
    if(this.value !== value) {
        value = this.value;
        //Do stuff
    }        
});

Aqui está um exemplo prático .

Ele simplesmente vincula um manipulador de eventos aos eventos keyup, changee click. Ele verifica se o valor foi alterado ou não e, em caso afirmativo, armazena o valor atual para que possa verificar novamente na próxima vez. O cheque é necessário para lidar com o clickevento.

James Allardice
fonte
Confundir o escopo global com uma variável chamada valueestá pedindo problemas.
AlienWebguy
Muito verdadeiro. Porém, como sua resposta, é apenas um exemplo. Acho que @JakeFeasel provavelmente tem a solução mais limpa.
James Allardice
1
$("input[type='number']").bind("focus", function() {
    var value = $(this).val();
    $(this).bind("blur", function() {
        if(value != $(this).val()) {
            alert("Value changed");
        }
        $(this).unbind("blur");
    });
});

OU

$("input[type='number']").bind("input", function() {
    alert("Value changed");
});
NK
fonte
1
<input type="number" id="n" value="0" step=".5" />
<input type="hidden" id="v" value = "0"/>

<script>
$("#n").bind('keyup mouseup', function () {
    var current = $("#n").val();
    var prevData = $("#v").val(); 
    if(current > prevData || current < prevData){
       $("#v").val(current);
       var newv = $("#v").val(); 
       alert(newv);
    } 
});  
</script>

http://jsfiddle.net/patrickrobles53/s10wLjL3/

Usei um tipo de entrada oculto para ser o contêiner do valor anterior que será necessário para a comparação na próxima alteração.

Patrick Robles
fonte
você pode usar apenas o data-prevatributo para armazenar o valor anterior. Não há necessidade de usar entrada extra
shukshin.ivan
1

Eu tive o mesmo problema e resolvi usando este código

HTML

<span id="current"></span><br>
<input type="number" id="n" value="5" step=".5" />

Você pode adicionar apenas 3 primeiras linhas, as outras partes são opcionais.

$('#n').on('change paste', function () {
    $("#current").html($(this).val())   
});
// here when click on spinner to change value, call trigger change
$(".input-group-btn-vertical").click(function () {
   $("#n").trigger("change");
});
// you can use this to block characters non numeric
$("#n").keydown(function (e) {
    // Allow: backspace, delete, tab, escape, enter and .
    if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110, 190]) !== -1 || (e.keyCode === 65 && e.ctrlKey === true) || (e.keyCode >= 35 && e.keyCode <= 40)) 
           return;

    if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) 
       e.preventDefault();
});

Exemplo aqui: http://jsfiddle.net/XezmB/1303/

Bruno Ribeiro
fonte