jQuery Змінити подію для елемента <input> - будь-яким способом зберегти попереднє значення?


75

Я шукав сьогодні вранці і не знайшов простих рішень ... по суті, я хочу зафіксувати зміну вхідного елемента, але також знати попереднє значення.

Ось подія зміни та елемент введення в найпростішій формі. Зрозуміло, що я можу отримати нове значення за допомогою $ (elem) .val (), але чи є підлий метод, який мені не вистачає для отримання попереднього значення? Я не бачу нічого в jQuery API для цього, але, можливо, хтось це вже зробив і має кілька порад?

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

Я не проти написання власного рішення, я просто хочу переконатись, що не відтворюю тут колесо.

Відповіді:


104

Кращий підхід - зберігати старе значення за допомогою .data. Це позбавляє від створення глобальної змінної, від якої слід триматися подалі, і зберігає інформацію, інкапсульовану всередині елемента. Реальний приклад світу, чому Global Варс погано документована тут

напр

<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
Щодня я дізнаюся щось нове про jQuery ... це перше, що я бачив .data (), тому я точно прочитаю про нього сьогодні.
SeanW

1
@redsquare - зовсім забув про .data () - приємно!
Russ Cam

1
@redsquare: Я не знав про .data. Дуже приємно :)
Даніель Моура

2
Неправда, навіть MS робить глобальні варіанти там скриптів ms ajax, які можуть перехопити людей, коли трапляється, що вони називають свій контроль так само, як глобальний var. Захист не є недосвідченою єдиною проблемою
redsquare

5
@redsquare: Це чудово, але, схоже, деяка логіка не зовсім правильна. .data('oldVal')встановлюється лише коли сторінка завантажується і ніколи після. Ймовірно , в changeабо focusподія має бути що - щось на зразок $(this).data('oldVal', $(this).val())?
Alex Angas

16

Це може зробити трюк:

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

Демо тут


2
Мені подобається це рішення, але йому бракує одного: якщо значення змінюється іншим кодом javascript (як у моєму випадку), або якщо вам потрібно старе значення вперше, цей код не буде працювати. Вам потрібно буде додати <input data-new="initialValue" />свій HTML, і ви повинні перезаписувати це значення під час кожної маніпуляції.
Александр Фишер

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

Найпростіший спосіб зробити це - мати більше голосів. Див: stackoverflow.com/questions/5244466 / ...
GreenieMeanie

Правда, це має бути прийнятою відповіддю: w3schools.com/jsref/prop_text_defaultvalue.asp
egdavid

2
Це неправильно, на моє розуміння попереднього значення . defaultValueце той, який був встановлений при завантаженні сторінки. Попереднє значення (на моє розуміння) - це значення елемента управління перед зміною. Якщо значення за замовчуванням - 1, а користувач - 2, то змінить його на 3, попереднє значення буде 2.
Сальман А

4

Ви можете скопіювати значення поля введення у приховане поле кожного разу, коли фокус залишає поле введення (яке має робити те, що ви хочете). Дивіться код нижче:

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

(не перевірено, але це має спрацювати).


Це не погана ідея ... Мені доведеться протестувати. Цікаво, чи спрацьовують події прив'язки та розмиття кожного разу в однаковому порядку ... якщо так, це може спрацювати. Як варіант, я можу мати можливість використовувати подію focus, щоб, коли елемент сфокусований, я зберігав значення. Потім при зміні я маю старі та нові значення ... Я проведу тестування і подивлюсь, що я можу придумати.
SeanW

Я провів тестування, і метод фокусування чудово працює. Дякую вам обом за ідеї / зразки!
SeanW,

2

Кожен елемент DOM має атрибут, який називається defaultValue. Ви можете використовувати це, щоб отримати значення за замовчуванням, якщо ви просто хочете порівняти першу зміну даних.


1

У відповіді Русса він пов’язує основну подію. Я не думаю, що це потрібно.

Ви можете зберегти старе значення у події зміни.

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

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

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

Даніеле, проблема в тому, що ти отримуєш старе значення лише один раз. Оскільки моя форма подається через веб-службу (ajax), документ завантажується лише один раз, але значення форми можуть змінюватися N разів. Використовуючи метод фокусування, я гарантовано отримаю нове вхідне значення.
SeanW

О, насправді - я бачу, що ти робиш ... моя помилка. Так, це теж спрацювало б.
SeanW,

1

Деякі моменти.

Використовуйте $ .data замість $ .fn.data

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

Тоді Ви можете отримати попереднє значення через об’єкт події, не ускладнюючи своє життя:

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

Зауважте, що defaultValue - НЕ останнє встановлене значення. Це значення, яким поле було ініціалізоване. Але ви можете використовувати $ .data для відстеження "oldValue"

Я рекомендую вам завжди оголошувати об'єкт "event" у своїх функціях обробника подій та перевіряти їх за допомогою firebug (console.log (event)) або чогось іншого. Ви знайдете там багато корисного, що позбавить вас від створення / доступу до об'єктів jquery (що чудово, але якщо ви можете бути швидшими ...)


1

Я створив ці функції на основі пропозиції Джої Герри, дякую за це. Я трохи розробляю, можливо, хтось може цим скористатися. Перша функція checkDefaults () викликається при зміні вводу, друга викликається, коли форма подається за допомогою jQuery.post. div.updatesubmit - це моя кнопка надсилання, а клас 'needsupdate' - показник того, що оновлення зроблено, але ще не надіслано.

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");
}

0

Я знайшов брудний трюк, але він працює, ви можете використовувати функцію наведення, щоб отримати значення перед зміною!


1
Це не буде працювати, якщо користувач використовує клавіатуру для переходу до вікна введення.
beetstra

1
А як щодо використання focus? що повинно зафіксувати і мишу, і клавіатуру
Стівен Лу
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.