繁体   English   中英

jQuery中的可变范围问题

[英]Variable Scope Issue in jQuery

我正在尝试在jQuery中捕获两个select元素的change()事件。 我试图以循环方式进行操作,因此不必剪切和粘贴相同的代码。

尽管var x = $("#"+fields[i]).val();这行还是有问题var x = $("#"+fields[i]).val();

fields = ['foo', 'bar'];

for (var i=0; i < fields.length; i++)
{
    $("#"+fields[i]).change(function () {
            var x = $("#"+fields[i]).val();
            alert(x);
    });
}

<form>
    <select id="foo">
        <option value="first">first</option>
        <option value="second">second</option>
    </select>
    <select id="bar">
        <option value="third">third</option>
        <option value="fourth">fourth</option>
    </select>
</form>

http://jsfiddle.net/mLc5p/6/

编辑

抱歉,这是一个过于简化的示例。 我实际上想得到一堆附近的字段,而不必进行一堆剪切和粘贴。 这是我的实际代码:

var fieldnames = ['start_date', 'end_date']
for (var i=0; i < fieldnames.length; i++)
{
    var fieldname = fieldnames[i];

$("#event_"+fieldname+"_date, #event_"+fieldname+"_hour, #event_"+fieldname+"_minute, #event_"+fieldname+"_ampm").change(function(){

    var d = $("#event_"+fieldname+"_date").val();
    var h = $("#event_"+fieldname+"_hour").val();
    var m = $("#event_"+fieldname+"_minute").val();
    var ampm = $("#event_"+fieldname+"_ampm").val();

    $("#event_"+fieldname).val(d + ' ' + h + ':' + m + ampm);

    if ( $("#event_"+fieldname).val() == " :" ){
        $("#event_"+fieldname).val("");
    }

    if (fieldname == "start_date")
    {
        $.validator.methods.validMoment.call(this, $("#event_"+fieldname).val(), $("#event_"+fieldname), null);
    }else
    {
        $.validator.methods.validOptionalMoment.call(this, $("#event_"+fieldname).val(), $("#event_"+fieldname), null);
    }
});

}

我想我可以只用Ruby生成代码,而不必担心用Javascript做任何技巧,但是我很好奇...

您应该将其更改为

$("#"+fields[i]).change(function () {
        var x = this.value;
        alert(x);
});

对于您的代码,问题在于无论您更改什么字段,都将始终显示last字段的值(由于for循环)。 换句话说:当发生change事件时, alert语句中的fields[i]的值始终显示 最后一个字段的值 未定义(如克里斯正确地提醒我)。

作为旁注,无需使用jQuery:您可以使用this.value

不...没有循环。 只需创建一个事件处理程序并使用this关键字即可获取正确的元素。

$("select").change(function(){
    var x = $(this).val();
    alert(x);
});

这是一个有效的例子

只需使用$.each进行迭代即可。

var fields = ['foo', 'bar'];

$.each(fields, function(idx, field){
     $("#"+field).change(function () {
            var x = $("#"+field).val();
            alert(x);
    });
});

http://jsfiddle.net/mLc5p/12/

这将解决范围问题。 问题是, i将是2后您的正常循环iteartion和i将不会被保存在每次迭代一个范围。 在您的处理程序的执行时间结束时, i将始终为2。 $.each会自动将每个迭代的范围分开。

为了完整起见,针对此问题的非jQuery解决方案是:

var fields = ['foo', 'bar'];

for (var i=0; i < fields.length; i++){
    (function(i){
       $("#"+fields[i]).change(function () {
            var x = $("#"+fields[i]).val();
            alert(x);
        });
    })(i);
}

具有与上述解决方案基本相同的效果。 您的代码被包装在一个函数中,并且我被“粘合”到您的函数范围中,作为自执行函数的参数。

你应该TRU this类似

var fields = ['foo', 'bar'];
for (var i=0; i < fields.length; i++)
{
    $("#"+fields[i]).change(function () {
        var x = $(this).val();// use this in place of fields[i]
        alert(x);
    });
}

工作小提琴

您需要在for循环中使用此指针。 小提琴

var fields = ['foo', 'bar'];

for (var i=0; i < fields.length; i++)
{
    $("#"+fields[i]).change(function () {
            var x = $(this).val();
            alert(x);
    });
}

尝试以下操作:

fields = ['foo', 'bar'];

for (var i=0; i < fields.length; i++)
{
    $("#"+fields[i]).change(function () {
        var x = $(this).val();
        alert(x);
    });
}

工作提琴: http : //jsfiddle.net/mLc5p/10/

更换:

var x = $("#"+fields[i]).val();  

至:

var x = $(this).val();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM