循环通过函数会导致错误,并在第一次更改时失败

Looping through function causes error and fails on first change

本文关键字:第一次 失败 错误 函数 循环      更新时间:2023-09-26

我这里有以下脚本,它导致了一些错误:

var sections = ["#general_info", "#address_records", "#employment_history", "#driver_experience", "#military_experience", "#eeo_survey", "#psp_notice", "#eva"];
for(var i = 0; i < sections.length; i++){ 
    $(sections[i]).find('input, select').each(function(){
        $(this).change(function(){
            validate();
            $(this).closest('.placement').find('.module-heading').removeClass('module-heading-bad');
            $(this).closest('.placement').find('.glyphicon').addClass('glyphicon-ok text-success');
            $(this).closest('.placement').find('.glyphicon').removeClass('glyphicon-warning-sign text-danger');
            $(sections[i]).find('input, select').each(function(){
                if($(this).closest('div').hasClass('has-error')){
                    $(this).closest('.placement').find('.module-heading').addClass('module-heading-bad');
                    $(this).closest('.placement').find('.glyphicon').addClass('glyphicon-warning-sign text-danger');
                    $(this).closest('.placement').find('.glyphicon').removeClass('glyphicon-ok text-success');
                    return false;
                }
            });
        });
    });
}
function validate(){
    var driving_qs = ['driving_exp_qa', 'driving_exp_qb', 'driving_exp_qc', 'driving_exp_qd'];
    for( var i = 0; i < driving_qs.length; i++){
        if($('input[name='+driving_qs[i]+']:checked').val()){
            $('input[name='+driving_qs[i]+']').closest('.form-group').removeClass('has-error');
            $('input[name='+driving_qs[i]+']').closest('.form-group').addClass('has-success');
        }else{
            $('input[name='+driving_qs[i]+']').closest('.form-group').addClass('has-error');
            $('input[name='+driving_qs[i]+']').closest('.form-group').removeClass('has-success');
        }
    }
    var fields = [{
        selector: $('.not-empty'),
        validations: [ isNotEmpty]
    },{
        selector: $('.email'),
        validations: [ isNotEmpty, isEmail]
    },{
        selector: $('.number'),
        validations: [ isNotEmpty, isNumber]
    },{
        selector: $('.number-noreq'),
        validations: [isNumberNotRequired]
    }];
    $('.form-control').closest('div').removeClass('has-error');
    var i = 0, k = 0, z = 0, j = fields.length, item, selector, fn, info;
    for(; i < j; i++){
        item = fields[i];
        for(k = 0; k < item.validations.length; k++){
            fn = item.validations[k];
            for( z = 0; z < item.selector.length; z++){
                selector = $(item.selector[z]);
                info = selector.closest('div');
                if(info)
                    var result = fn(selector.val());
                if(result){
                    info.removeClass("has-error");
                    info.addClass('has-success');
                }else{
                    info.removeClass('has-success');
                    info.addClass("has-error")
                }
            }
        }
    }
}

如果我在没有for循环的情况下运行脚本,它的工作效果非常好。以下是我的代码的快速步骤(注意:这没有for循环):

  1. 找到代码中的部分,并为每个输入找到一个选择字段
  2. 将更改事件分配给每个目标输入和选择字段
  3. 在更改时,找到最接近的类放置范围,并对第一个模块标题进行微调,并执行所有类的添加和删除操作,只是为了在下面不存在错误的情况下将标题刷新为成功标题
  4. 查找所有输入,选择并检查错误,如果存在错误,则返回false,并将错误类添加回所有内容

这个脚本将一直工作到每个部分的末尾,就像它应该做的那样。然而,在我尝试用for loop完成这项工作后,它只需一次输入就创建了一个成功的场景。为什么会发生这种情况,是否有可能像我目前所做的那样在循环中使用这个函数?

下面我还包括了html标记的示例

<!-- this tag serves no purpose other than being a bookmark for scripting -->
<span class='placement'>
    <!-- Section 1: General Information  -->
    <div id='general-heading' class='row module-heading module-heading-bad general' data-toggle='#general_info'>
        <div class='form-group'>
            <div class='col-md-12'>
                <h4 class='text-info '>General Information<div id='general-confirmation' class='glyphicon glyphicon-warning-sign pull-right text-danger'></div></h4>    
            </div>
        </div>
    </div>
    <div id='general_info' class='app-section'>
        <div class='form-group'>
            <div class='col-xs-12'>
                <div class='form-group row'>
                    <div class='col-sm-6 col-xs-12'>    
                        <label class='control-label'>First Name<span class='req'> *</span></label><br />
                        <input type='text' class='form-control not-empty' id='first_name' value="<?=$first_name?>"/>
                    </div>
                    <div class='col-sm-6 col-xs-12'>
                        <label class='control-label'>Middle Name</label><br />
                        <input type='text' class='form-control' id='middle_name' value="<?=$middle_name?>"/>
                    </div>
                </div>
            </div>
        </div>
</span>

此代码块中的问题:

for(var i = 0; i < sections.length; i++){ 
    $(sections[i]).find('input, select').each(function(){
        $(this).change(function(){
            ...
            $(sections[i]).find('input, select').each(function(){
                ...
                }
            });
        });
    });
}

它使用了变量i,当change中的function()运行时,该变量将发生更改。

在您的情况下,修复它的最简单方法是使用forEach函数而不是for循环,并且根本不使用索引:

sections.forEach(function(section){ 
    $(section).find('input, select').each(function(){
        $(this).change(function(){
            ...
            $(section).find('input, select').each(function(){
                ...
                }
            });
        });
    });
})

这将确保您所指的i每次都不同。