evento onchange para el tipo de entrada = "número"

85

¿Cómo puedo manejar un cambio <input type="number" id="n" value="5" step=".5" />? No puedo hacer un keyupo keydown, porque el usuario puede usar las flechas para cambiar el valor. Me gustaría manejarlo cada vez que cambie, no solo en el desenfoque, que creo que hace el .change()evento. ¿Algunas ideas?

Ian Davis
fuente
2
¿Se da cuenta de que el tipo de entrada no es compatible con IE o Firefox?
AlienWebguy
Ahora es compatible con Firefox
ElephantHunter
2
caniuse.com/#feat=input-number Sí, estoy comentando una pregunta de hace seis años.
Pete

Respuestas:

134

Usar mouseup y keyup

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

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

JohnColvin
fuente
4
Esto alertará incluso si el valor no ha cambiado (simplemente haga clic en cualquier parte del input).
James Allardice
Sí lo será. Si eso es un problema, debe realizar un seguimiento del valor en la entrada en una variable global o en un elemento de datos en la entrada. Cuando el evento mouseup llame a su función, compare ese valor con el valor actual de la entrada. Solo haga algo si el valor ha cambiado.
JohnColvin
3
Esto no funciona si el valor se cambia con el desplazamiento del mouse sobre el elemento.
Ondrej Machulda
7
Agregue el evento "mousewheel" para admitir cambios mediante el desplazamiento.
Martijn
4
Si el usuario mantiene presionada una tecla de flecha para cambiar el valor, esto no se activa hasta que se suelta la tecla de flecha. Usar en su inputlugar (como se sugiere en otra respuesta) parece funcionar mejor.
Josh Kelley
75

El oninputevento ( .bind('input', fn)) cubre cualquier cambio desde las pulsaciones de teclas hasta los clics de las flechas y el pegado del teclado / mouse, pero no es compatible con 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
fuente
9

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());
});​

Esto es un poco gueto, pero de esta manera puede usar el evento "click" para capturar el evento que se ejecuta cuando usa el mouse para incrementar / disminuir a través de las flechas pequeñas en la entrada. Puede ver cómo he incorporado una pequeña rutina manual de "verificación de cambios" que garantiza que su lógica no se active a menos que el valor realmente cambie (para evitar falsos positivos de simples clics en el campo).

Jake Feasel
fuente
6

Para detectar cuándo se presiona el mouse o la tecla, también puede escribir:

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

Demostración: http://jsfiddle.net/X8cV3/

AlienWebguy
fuente
Esto aún se ejecutará si el valor no ha cambiado (simplemente haga clic en cualquier parte del input).
James Allardice
Esto es cierto, pero una vez que captura el evento, puede determinar si el valor ha cambiado o no.
AlienWebguy
3

Debido a $("input[type='number']")que no funciona en IE, deberíamos usar un nombre de clase o id, por ejemplo $('.input_quantity'),.

Y no uses el .bind()método. El .on()método es el método preferido para adjuntar controladores de eventos a un documento.

Entonces, mi versión es:

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
fuente
1

Puede que haya una solución mejor, pero esto es lo que me vino a la mente:

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

Aquí tienes un ejemplo práctico .

Simplemente se une a un controlador de eventos a los keyup, changey clickeventos. Comprueba si el valor ha cambiado o no y, de ser así, almacena el valor actual para poder comprobarlo de nuevo la próxima vez. El cheque es necesario para hacer frente al clickevento.

James Allardice
fuente
Abarrotar el ámbito global con una variable nombrada valuees buscar problemas.
AlienWebguy
Muy cierto. Sin embargo, como su respuesta, es solo un ejemplo. Creo que @JakeFeasel probablemente tenga la solución más limpia.
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");
    });
});

O

$("input[type='number']").bind("input", function() {
    alert("Value changed");
});
NK
fuente
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/

He utilizado un tipo de entrada oculta para que sea el contenedor del valor anterior que se necesitará para la comparación en el próximo cambio.

Patrick Robles
fuente
puede usar solo el data-prevatributo para almacenar el valor anterior. No es necesario utilizar información adicional
shukshin.ivan
1

Tuve el mismo problema y lo resolví usando este código.

HTML

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

Puede agregar solo 3 primeras líneas, las otras partes son opcionales.

$('#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();
});

Ejemplo aquí: http://jsfiddle.net/XezmB/1303/

Bruno Ribeiro
fuente