如何在for循环中附加onchange处理程序

时间:2012-10-12 18:12:49

标签: javascript event-handling

我有一个for循环遍历表单中的依赖字段。该数组如下所示:

var dependentFields = [
    { parent: FLDID_LABEL, children: [FLDID_LABEL_TEMPLATE, FLDID_LABEL_INSTRUCTIONS], choiceTrigger: 'Yes', markAsReq: true },
    { parent: FLDID_SHIP_TO, children: [FLDID_SHIP_TO_ADDR], choiceTrigger: 'No', markAsReq: true }
];

我有一个函数被调用来附加所有事件处理程序。为简单起见,我将仅显示问题发生的循环。

function attachEventHandlers() {
    // begin dependent fields
    for (var i = 0; i < dependentFields.length; i++) {
        var o = dependentFields[i];
        $('#' + o.parent).change(function () {
            var visible = $('#' + o.parent + ' :selected').text() === o.choiceTrigger;
            for (var c = 0; c < o.children.length; c++) {
                var child = o.children[c];
                showField(child, visible);
                if (o.markAsReq && $('#' + child).val() === '') {
                    MarkFieldAsRequired(child);
                }
            }
        });
    }
}

只有第二个依赖字段有效,第一个字段不起作用。我认为这与从外部函数引用var ivar o的方式有关。实际上,相同的事件处理程序将附加到所有依赖字段。我该如何解决这个问题?

编辑:这是一个有错误的jsfiddle:http://jsfiddle.net/H3Bv2/4/ 请注意,更改父母中的任何一方只会影响第二个孩子。

2 个答案:

答案 0 :(得分:1)

在这里查看解决方案:JavaScript closure inside loops – simple practical example

您的原始代码引用在循环中创建的每个回调函数中的单个变量o - 并且在每次迭代时都会重新分配该变量的值,因此所有回调最终都使用最后值已分配。

答案 1 :(得分:0)

我明白了。使用jQuery.each让我避免在循环中定义变量。 这是我的解决方案:

function attachEventHandlers() {
    // begin dependent fields
    $.each(dependentFields, function (i, o) {
        $('#' + o.parent).change(function () {
            var visible = $(':selected', this).text() === o.choiceTrigger;
            for (var c = 0; c < o.children.length; c++) {
                var child = o.children[c];
                showField(child, visible);
                if (o.markAsReq && $('#' + child).val() === '') {
                    MarkFieldAsRequired(child);
                }
            }
        });
    });
}