2

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

这条线虽然有问题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 做任何技巧,但我很好奇......

4

7 回答 7

2

你应该把它改成

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

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

作为旁注,不需要使用 jQuery:你可以使用this.value

于 2013-08-02T11:14:54.130 回答
1

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

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

这是一个工作示例

于 2013-08-02T11:14:43.903 回答
1

$.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在您的正常 for 循环迭代之后将是 2 并且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);
}

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

于 2013-08-02T11:18:50.903 回答
0

代替:

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

至:

var x = $(this).val();
于 2013-08-02T11:17:37.607 回答
0

你应该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);
    });
}

工作小提琴

于 2013-08-02T11:15:01.557 回答
0

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

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

for (var i=0; i < fields.length; i++)
{
    $("#"+fields[i]).change(function () {
            var x = $(this).val();
            alert(x);
    });
}
于 2013-08-02T11:15:26.250 回答
0

尝试以下:

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/

于 2013-08-02T11:15:47.523 回答