<input>元素上的jQuery Change事件-是否可以保留以前的值?


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

我并不反对编写自己的解决方案,我只是想确保我不在这里重新创建轮子。

Answers:


104

更好的方法是使用.data存储旧值。这样可以避免创建全局变量,您应该远离全局变量,并将信息封装在元素中。此处记录为何Global Vars不好的一个真实示例

例如

<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。非常好:)
Daniel Moura

2
事实并非如此,甚至MS都在其中的ms ajax脚本中渲染全局变量,当人们碰巧将其控件命名为全局变量时,它们可以捕获人们。Def不是一个没有经验的唯一问题
Redsquare

5
@redsquare:很好,但是看起来有些逻辑并不正确。.data('oldVal')仅在页面加载时设置,以后再设置。在changefocus事件中可能应该是类似的东西$(this).data('oldVal', $(this).val())
亚历克斯·安加斯

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 2015年

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


1

在拉斯回答中,他绑定了焦点事件。我认为没有必要。

您可以将旧值存储在change事件中。

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

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

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

丹尼尔(Daniel),这样做的问题是您只获得了旧值一次。因为我的表单是通过Web服务(ajax)提交的,所以文档仅加载一次,但是表单值可以更改N次。通过使用focus方法,可以确保获得新的输入值。
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”

我建议您始终在事件处理程序函数中声明“事件”对象,并使用firebug(console.log(event))进行检查。您会在这里找到很多有用的东西,这些东西将使您不必创建/访问jquery对象(这很好,但是如果可以更快...)


1

我根据Joey Guerra的建议创建了这些功能,谢谢。我正在详细说明,也许有人可以使用它。输入更改时,将调用第一个函数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");
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.