1

我正在开发带有进度条的 ajax 上传,如果文件输入不是多个没有问题,但我想开发多个 ajax 上传,因此我创建一个“for”循环,直到用户选择的文件数量.

当函数进入这里时,indice 的值就是 len 变量的值,为什么会出现这种情况呢?

 myXhr.upload.addEventListener('progress', function(e) { progressHandlingFunction(e, '.prog'+(indice)) }, false);

完整代码:

<script type="text/javascript">
    $(document).ready(function(e){
        $('#uploader').submit(function(){
            var inpf = document.getElementById('files');
            var len = inpf.files.length;
            //console.log(inpf, len);return false;
            for(var i=0; i<len; i++){
                var indice = i;
                $('div').append('<progress class="prog'+i+'" value="0"></progress><br />');
                var formData = new FormData();
                formData.append('image', inpf.files[i]);
                $.ajax({
                    url: 'upload1.php',  //server script to process data
                    type: 'POST',
                    xhr: function() {  // custom xhr
                        var myXhr = $.ajaxSettings.xhr();
                        if(myXhr.upload){ // check if upload property exists
                            myXhr.upload.addEventListener('progress', function(e) { progressHandlingFunction(e, '.prog'+(indice)) }, false); // for handling the progress of the upload
                        }
                        return myXhr;
                    },
                    //Ajax events
                    //beforeSend: beforeSendHandler,
                    success: function(data){
                        completeHandler(data, '.prog'+i);
                    },
                    //error: errorHandler,
                    // Form data
                    data: formData,
                    //Options to tell JQuery not to process data or worry about content-type
                    cache: false,
                    contentType: false,
                    processData: false,
                });
            }
            return false;
        });
    });

    function progressHandlingFunction(e, klass){
        if(e.lengthComputable){
            $(klass).attr({value:e.loaded, max:e.total});
        }
    }

    function completeHandler(data, klass){
        $(klass).attr({value:0});
    }
</script>

这里有带有示例的 jsFiddle:http: //jsfiddle.net/Pgq9s/

4

2 回答 2

3

该变量i的作用域是整个函数,而不是for循环的特定迭代。当你的success回调函数被执行时,for循环将完全执行,并且i在最后一次迭代之后将等于它的值(so i == len)。

使用立即调用的函数表达式创建一个闭包,保留该i迭代的值:

for(var i=0; i<len; i++){
    var indice = i;
    $('div').append('<progress class="prog'+i+'" value="0"></progress><br />');
    var formData = new FormData();
    formData.append('image', inpf.files[i]);
    (function(index) {
    $.ajax({
        url: 'upload1.php',  //server script to process data
        type: 'POST',
        xhr: function() {  // custom xhr
            var myXhr = $.ajaxSettings.xhr();
            if(myXhr.upload){ // check if upload property exists
                myXhr.upload.addEventListener('progress', function(e) { progressHandlingFunction(e, '.prog'+(index)) }, false); // for handling the progress of the upload
            }
            return myXhr;
        },
        //Ajax events
        //beforeSend: beforeSendHandler,
        success: function(data){
            completeHandler(data, '.prog'+index);
        },
        //error: errorHandler,
        // Form data
        data: formData,
        //Options to tell JQuery not to process data or worry about content-type
        cache: false,
        contentType: false,
        processData: false,
    });
    })(i);
}
于 2013-05-13T11:52:31.877 回答
2

循环启动了很多 ajax 请求。一旦所有请求都开始, i它是最大值。

然后 ajax 请求的结果开始出现,并success执行您的回调函数。i执行所有回调时仍将处于最大值。

于 2013-05-13T11:51:27.277 回答