Pregunta jQuery Cambiar evento en un elemento - ¿hay alguna forma de retener el valor anterior?


He estado buscando esta mañana y no encuentro ninguna solución simple ... básicamente, quiero capturar un cambio en un elemento de entrada, pero también conocer el valor anterior.

Aquí hay un evento de cambio y un elemento de entrada en su forma más simple. Claramente, puedo obtener el nuevo valor con $ (elem) .val (), pero ¿hay algún método furtivo que me falte para obtener el valor anterior? No veo nada en la API de jQuery para hacer esto, pero ¿alguien ya lo ha hecho y tiene algunos consejos?

<script>
    $(document).ready(function(){
        $('#myInputElement').bind('change', function(){
            //var oldvalue = ???
            var newvalue = $(this).val();
        });
    });
</script>
<input id="myInputElement" type="text">

No estoy en contra de escribir mi propia solución, solo quiero asegurarme de que no estoy recreando la rueda aquí.


74
2017-07-21 13:02


origen


Respuestas:


Un mejor enfoque es almacenar el valor anterior usando .data. Esto evita la creación de una var global de la que debe mantenerse alejado y mantiene la información encapsulada dentro del elemento. Un ejemplo del mundo real de por qué Global Vars es malo está documentado aquí

p.ej

<script>
    //look no global needed:)

    $(document).ready(function(){
        // Get the initial value
       var $el = $('#myInputElement');
       $el.data('oldVal',  $el.val() );


       $el.change(function(){
            //store new value
            var $this = $(this);
            var newValue = $this.data('newVal', $this.val());
       })
       .focus(function(){
            // Get the value when input gains focus
            var oldValue = $(this).data('oldVal');
       });
    });
</script>
<input id="myInputElement" type="text">

103
2017-07-21 13:38



Esto podría hacer el truco:

$(document).ready(function() {
    $("input[type=text]").change(function() {
        $(this).data("old", $(this).data("new") || "");
        $(this).data("new", $(this).val());
        console.log($(this).data("old"));
        console.log($(this).data("new"));
    });
});

Demo aquí


15
2017-07-14 11:46



$('#element').on('change', function() {
    $(this).val($(this).prop("defaultValue"));
});

9
2018-04-18 10:19



Puede tener el valor del campo de entrada copiado en un campo oculto cada vez que el foco abandona el campo de entrada (que debe hacer lo que desee). Vea el código a continuación:

<script>
    $(document).ready(function(){
        $('#myInputElement').bind('change', function(){
            var newvalue = $(this).val();
        });
        $('#myInputElement').blur(function(){
            $('#myHiddenInput').val($(this).val());
        });
    });
</script>
<input id="myInputElement" type="text">

(no probado, pero debería funcionar).


4
2017-07-21 13:06



Cada elemento DOM tiene un atributo llamado defaultValue. Puede usar eso para obtener el valor predeterminado si solo quiere comparar el primer cambio de datos.


2
2018-04-28 19:44



En la respuesta de Russ, vincula el evento de enfoque. No creo que sea necesario.

Puede almacenar el valor anterior en el evento de cambio.

<script>
    $(document).ready(function(){

        var newValue = $('#myInputElement').val();
        var oldValue;

        $('#myInputElement').change(function(){
            oldValue = newValue;
            newValue = $(this).val();
        });
    });
</script>
<input id="myInputElement" type="text">

1
2017-07-21 13:35



Algunos puntos.

Use $ .data en lugar de $ .fn.data

// regular
$(elem).data(key,value);
// 10x faster
$.data(elem,key,value);

Luego, puede obtener el valor anterior a través del objeto del evento, sin complicar su vida:

    $('#myInputElement').change(function(event){
        var defaultValue = event.target.defaultValue;
        var newValue = event.target.value;
    });

Tenga en cuenta que defaultValue NO es el último valor establecido. Es el valor con el que se inicializó el campo. Pero puede usar $ .data para realizar un seguimiento del "oldValue"

Le recomiendo que siempre declare el objeto "evento" en las funciones de su controlador de eventos e inspeccione con firebug (console.log (evento)) o algo así. Encontrarás muchas cosas útiles allí que te ahorrarán la creación / acceso a objetos jquery (que son geniales, pero si puedes ser más rápido ...)


1
2018-05-30 09:48



Creé estas funciones según la sugerencia de Joey Guerra, gracias por eso. Estoy elaborando un poco, quizás alguien pueda usarlo. La primera función checkDefaults () se invoca cuando una entrada cambia, la segunda se invoca cuando el formulario se envía utilizando jQuery.post. div.updatesubmit es mi botón de envío, y la clase 'needsupdate' es un indicador de que se ha realizado una actualización pero aún no se ha enviado.

function checkDefaults() {
    var changed = false;
        jQuery('input').each(function(){
            if(this.defaultValue != this.value) {
                changed = true;
            }
        });
        if(changed === true) {
            jQuery('div.updatesubmit').addClass("needsupdate");
        } else {
            jQuery('div.updatesubmit').removeClass("needsupdate");
        }
}

function renewDefaults() {
        jQuery('input').each(function(){
            this.defaultValue = this.value;
        });
        jQuery('div.updatesubmit').removeClass("needsupdate");
}

1
2017-12-06 00:02



Encontré un truco sucio pero funciona, ¡podrías usar la función de desplazamiento para obtener el valor antes del cambio!


0
2018-02-12 14:39