2009-07-21 10 views
74

Szukałem dziś rano i nie znajduję żadnych prostych rozwiązań ... w zasadzie chcę uchwycić zmianę w elemencie wejściowym, ale także znać poprzednią wartość.jQuery Zmień wydarzenie na element <input> - jakikolwiek sposób na zachowanie poprzedniej wartości?

Oto zdarzenie zmiany i element wejściowy w najprostszej postaci. Oczywiście, mogę uzyskać nową wartość za pomocą $ (elem) .val(), ale czy istnieje podstępna metoda, której mi brakuje do uzyskania poprzedniej wartości? Nie widzę w tym nic w API jQuery, ale może ktoś już to zrobił i ma kilka wskazówek?

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

Nie jestem przeciwny pisaniu własnego rozwiązania, chcę tylko upewnić się, że nie odtwarzam tutaj koła.

Odpowiedz

104

Lepszym rozwiązaniem jest przechowywanie starej wartości za pomocą .data. Zapobiega to tworzeniu globalnego var, którego należy unikać i zachowuje informacje zawarte w elemencie. Prawdziwy przykład świat, dlaczego globalne Vars są złe jest udokumentowana here

np

<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"> 
+1

Każdego dnia uczę się czegoś nowego o jQuery ... jest to pierwszy, jaki widziałem .data(), więc na pewno jeszcze o tym przeczytam. – SeanW

+1

@redsquare - całkowicie zapomniałem o .data() - miło! –

+1

@redsquare: Nie wiedziałem o .data. Bardzo miło :) –

4

Możesz mieć wartość pola wejściowego skopiowanego do ukrytego pola, gdy fokus opuszcza pole wejściowe (które powinno zrobić to, co chcesz). Zobacz kod poniżej:

<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"> 

(untested, ale powinno działać).

+0

To nie jest zły pomysł ... Muszę przetestować. Zastanawiam się, czy zdarzenia powiązań i rozmycia są uruchamiane w tej samej kolejności za każdym razem ... jeśli tak, to może działać. Alternatywnie, mogę być w stanie użyć zdarzenia skupienia, więc gdy element jest skupiony, przechowuję wartość. Potem po zmianie mam stare i nowe wartości ... Zrobię test i zobaczę, co wymyślę. – SeanW

+0

Zrobiłem kilka testów, a metoda skupienia działa doskonale. Dziękuję wam za pomysły/próbki! – SeanW

1

W odpowiedzi Russ wiąże on fokus. Nie uważam tego za konieczne.

Możesz zachować starą wartość w zdarzeniu zmiany.

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

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

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

Daniel, problem polega na tym, że raz otrzymujesz starą wartość. Ponieważ moja forma przesyła za pośrednictwem usługi sieciowej (ajax), dokument ładuje się tylko raz, ale wartości formularza mogą zmieniać liczbę N razy. Korzystając z metody ustawiania ostrości, mam pewność, że podniosę nową wartość wejściową. – SeanW

+0

O tak, widzę, co robisz ... mój błąd. Tak, to też by działało. – SeanW

2

elementem Każdy DOM posiada atrybut o nazwie defaultValue. Możesz użyć tego, aby uzyskać wartość domyślną, jeśli chcesz porównać pierwszą zmianę danych.

1

Kilka punktów.

Zastosowanie $ .data Zamiast $ .fn.data

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

Następnie można uzyskać poprzednią wartość przez obiekt zdarzenia, bez komplikowania swoje życie:

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

Be ostrzegł, że defaultValue NIE jest ostatnią ustawioną wartością. Jest to wartość, z którą zainicjowano pole. Ale możesz użyć $ .data do śledzenia "starej wartości"

Polecam zawsze zadeklarować obiekt "event" w funkcjach obsługi zdarzeń i sprawdzić je za pomocą firebug (console.log (event)) lub coś podobnego. Znajdziesz tam wiele przydatnych rzeczy, które pozwolą ci zaoszczędzić od tworzenia/uzyskiwania dostępu do obiektów jQuery (które są świetne, ale jeśli możesz być szybszy ...)

15

Może to rade:

$(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 here

+2

Podoba mi się to rozwiązanie, ale brakuje mu jednej rzeczy: jeśli wartość zostanie zmieniona przez inny kod javascript (tak jak w moim przypadku) lub jeśli potrzebujesz starej wartości po raz pierwszy, ten kod nie zadziała. Będziesz musiał dodać '' w kodzie HTML i musisz nadpisać tę wartość przy każdej manipulacji. –

+1

To powinno być # 1 – gkunz

0

znalazłem świństwo, ale to działa, można użyć funkcji aktywowanych uzyskać wartość przed zmianą!

+1

To nie zadziała, jeśli użytkownik użyje klawiatury, aby przejść do pola wprowadzania. – beetstra

+1

Co z użyciem 'focus'?to powinno złapać mysz i klawiaturę. –

1

Te funkcje stworzyłem w oparciu o sugestię Joey'a Guerry, dziękuję za to. Trochę się rozwijam, może ktoś może z tego skorzystać. Pierwsza funkcja checkDefaults() jest wywoływana, gdy dane wejściowe ulegają zmianie, druga funkcja jest wywoływana, gdy formularz jest wysyłany za pomocą jQuery.post. div.updatesubmit to mój przycisk przesyłania, a klasa "needsupdate" jest wskaźnikiem, że aktualizacja została wprowadzona, ale jeszcze nie została przesłana.

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"); 
} 
9
$('#element').on('change', function() { 
    $(this).val($(this).prop("defaultValue")); 
}); 
+0

Najprostszy sposób to zrobić - powinien mieć więcej głosów. Zobacz: http://stackoverflow.com/questions/5244466/how-safe-reliable-cross-browser-compatible-is-this0-defaultvalue – GreenieMeanie

+0

Prawda, to powinna być zaakceptowana odpowiedź: http://www.w3schools.com /jsref/prop_text_defaultvalue.asp – roastedtoast

+1

Jest to niepoprawne zgodnie z moim rozumieniem _poprzedniej wartości_. 'defaultValue' to ta, która została ustawiona podczas ładowania strony. Poprzednia wartość (zgodnie z moim rozumieniem) jest wartością kontrolną przed zmianą. Jeśli domyślną wartością jest 1, a użytkownik 2, a następnie zmieni się na 3, poprzednia wartość_ wynosiłaby 2. –

Powiązane problemy