进度条显示不正确 - 使用ajax上传文件

时间:2015-01-19 09:56:03

标签: jquery ajax file-upload xmlhttprequest jqxhr

for( var i=0; i<=input.length-1; i++ )
{

    // Append all files in the formData.
    formData.append( 'files[]', input[i] );

    // Create progress element.
    var progressElement = jQuery( '<li class="working"><input type="text" value="0" data-width="32" data-height="32"'+
            ' data-fgColor="#0788a5" data-readOnly="1" data-bgColor="#3e4043" /><p></p><span></span></li>' );

    // Append the file name and file size.
    var fileName = fileContentArray[i];

    progressElement.find( 'p' ).text( fileName )
    .append( '<i>' + fileSizeArray[i] + '</i>' );

    // Add the HTML to the UL element.
    progressElement.appendTo( jQuery( '#upload ul' ) );

    // Initialize the knob plugin.
    progressElement.find( 'input' ).knob();

    // Ajax function.
    formData.append( 'action', 'auto_post' );
    jQuery.ajax
    ({
        url: ajaxurl,
        type: "POST",
        data: formData,
        processData: false,
        contentType: false,
        xhr: function()
        {
            var xhr = new window.XMLHttpRequest();
            xhr.upload.addEventListener( 'progress', function( e )
            {
                if( e.lengthComputable )
                {
                    // Append progress percentage.
                    var progressValue = ( e.loaded / e.total ) * 100;
                    console.log( i + ':' + progressValue );
                    progressElement.find( 'input' ).val( progressValue ).change();

                    // Listen for clicks on the cancel icon.
                    progressElement.find( 'span' ).click( function()
                    {
                        if( progressElement.hasClass( 'working' ) )
                        {
                            xhr.abort();
                        }

                        progressElement.fadeOut( function()
                        {
                            progressElement.remove();
                        });
                    });

                    if( progressValue == 100 )
                    {
                        progressElement.removeClass( 'working' );
                    }
                }
            }, false);
            return xhr;
        }
   });
}

<code>Sample1</code>

以上代码完美地上传文件。如图所示,只有最后一张图像有所进展。执行console.log( i + ':' + progressValue );时,这也表示仅附加最后一个图像进度。

更有趣的是,如果我在下面发出警告:

    xhr: function()
    {
        alert('f');
        var xhr = new window.XMLHttpRequest();
        xhr.upload.addEventListener( 'progress', function( e )

然后我得到的输出是这样的:

<code>Sample 2</code>

然后我使用了setTimeout功能,但这对我也没有帮助。是什么导致这种行为?我希望你们的人能理解我的问题。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

这是因为你在循环中这样做......

i变量将始终是最后一个。

您可以在闭包内执行操作以防止这种情况......

for( var i=0; i<=input.length-1; i++ )
{

(function(i) {

// Append all files in the formData.
formData.append( 'files[]', input[i] );

// Create progress element.
var progressElement = jQuery( '<li class="working"><input type="text" value="0" data-width="32" data-height="32"'+
        ' data-fgColor="#0788a5" data-readOnly="1" data-bgColor="#3e4043" /><p></p><span></span></li>' );

// Append the file name and file size.
var fileName = fileContentArray[i];

progressElement.find( 'p' ).text( fileName )
.append( '<i>' + fileSizeArray[i] + '</i>' );

// Add the HTML to the UL element.
progressElement.appendTo( jQuery( '#upload ul' ) );

// Initialize the knob plugin.
progressElement.find( 'input' ).knob();

// Ajax function.
formData.append( 'action', 'auto_post' );
jQuery.ajax
({
    url: ajaxurl,
    type: "POST",
    data: formData,
    processData: false,
    contentType: false,
    xhr: function()
    {
        var xhr = new window.XMLHttpRequest();
        xhr.upload.addEventListener( 'progress', function( e )
        {
            if( e.lengthComputable )
            {
                // Append progress percentage.
                var progressValue = ( e.loaded / e.total ) * 100;
                console.log( i + ':' + progressValue );
                progressElement.find( 'input' ).val( progressValue ).change();

                // Listen for clicks on the cancel icon.
                progressElement.find( 'span' ).click( function()
                {
                    if( progressElement.hasClass( 'working' ) )
                    {
                        xhr.abort();
                    }

                    progressElement.fadeOut( function()
                    {
                        progressElement.remove();
                    });
                });

                if( progressValue == 100 )
                {
                    progressElement.removeClass( 'working' );
                }
            }
        }, false);
        return xhr;
    }
  });

})(i);

}