为什么我的HTML5进度条没有随jQuery AJAX而改变?

时间:2014-10-30 03:34:53

标签: javascript jquery ajax html5

我正在尝试为我的jQuery / AJAX上传脚本创建一个进度条。脚本中的所有内容都可以正常工作,但进度条的值永远不会改变。此外,在控制台中,percentComplete变量始终为1,并且它会记录两次。我尝试过各种不同的东西,但似乎没什么用。进度条本身被添加到我的div中,但是关于它。

$.ajax({
    beforeSend : function(){
        $(settings.message_div).html('<progress id="#upload-progress" value="0" max="100"></progress>');
    },
    xhr: function()
    {
        var xhr = new window.XMLHttpRequest();
        //Upload progress
        xhr.upload.addEventListener("progress", function(evt){
            if (evt.lengthComputable) {
                var percentComplete = evt.loaded / evt.total;
                //Do something with upload progress
                console.log(percentComplete);
                $('#upload-progress').val(percentComplete);
            }
        }, false);
        //Download progress
        xhr.addEventListener("progress", function(evt){
            if (evt.lengthComputable) {
                var percentComplete = evt.loaded / evt.total;
                //Do something with download progress
                console.log(percentComplete);
                $('#upload-progress').val(percentComplete);
            }
        }, false);
    return xhr;
     },
    type: "POST",
    dataType: "xml",
    data: formData,
    url: settings.ajax_url,
    processData: false,
    contentType: false,
    cache: false,
    success: function(xml){
        //console.log('ajax called');
    },
    error: function(xhr){
        $(settings.message_div).html(xhr.responseText);
        //console.log(xhr.responseText);
    }
});

这取自here

2 个答案:

答案 0 :(得分:1)

onprogress最近应该有效。您看到的教程有点过时了。 http://www.html5rocks.com/en/tutorials/file/xhr2/
http://www.w3.org/TR/progress-events/#introduction

xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
  var progressBar = $('#upload-progress').get(0);
  progressBar.value = (e.loaded / e.total) * 100;
  progressBar.textContent = progressBar.value; // Fallback for unsupported browsers.
}

答案 1 :(得分:0)

您跟随的tutorial 真的旧,可能与Jquery 1.5相关。但是在该版本中,旧的XHR对象已被隐藏,并被具有更高抽象级别的JQXhr对象替换:

  

jQuery 1.5中$ .ajax()返回的jQuery XMLHttpRequest(jqXHR)对象是浏览器的原生XMLHttpRequest对象的超集。例如,它包含responseText和responseXML属性,以及getResponseHeader()方法。当传输机制不是XMLHttpRequest(例如,JSONP请求的脚本标记)时,jqXHR对象会尽可能模拟本机XHR功能。

此对象的属性没有很好地记录,我不确定它是否仍然支持您尝试在代码中利用的uploadprogress功能。

即使在该博客的评论中,人们建议使用onprogress选项中的xhrFields属性,但再次this SO Post确认在较新版本的版本中不可能Jquery已被弃用。仅在该帖子中,答案表明:

  

xhr 选项参数必须是一个函数,它返回一个本机XmlHttpRequest对象供jQuery使用。

来自the answer的代码段:

 $.ajax({
async: true,
contentType: file.type,
data: file,
dataType: 'xml',
processData: false,
success: function(xml){
    // Do stuff with the returned xml
},
type: 'post',
url: '/fileuploader/' + file.name,
xhr: function(){
    // get the native XmlHttpRequest object
    var xhr = $.ajaxSettings.xhr() ;
    // set the onprogress event handler
    xhr.upload.onprogress = function(evt){ console.log('progress', evt.loaded/evt.total*100) } ;
    // set the onload event handler
    xhr.upload.onload = function(){ console.log('DONE!') } ;
    // return the customized object
    return xhr ;
} ;
});

另一个relevant Answer在类似的行上,他使用deferred object's progress属性并定义其中的上传进度事件处理程序。

TLDR - 如果您可以使用本机XHR对象并利用它在最新版本的Jquery中提及的上传和进度事件,则无法建立。< / p>

您应该查看一些HTML5和jquery文件上传插件的代码。我刚刚在github上浏览one,我只是在项目中复制粘贴来自fileupload.js的代码:

        _onProgress: function (e, data) {
        if (e.lengthComputable) {
            var now = ((Date.now) ? Date.now() : (new Date()).getTime()),
                loaded;
            if (data._time && data.progressInterval &&
                    (now - data._time < data.progressInterval) &&
                    e.loaded !== e.total) {
                return;
            }
            data._time = now;
            loaded = Math.floor(
                e.loaded / e.total * (data.chunkSize || data._progress.total)
            ) + (data.uploadedBytes || 0);
            // Add the difference from the previously loaded state
            // to the global loaded counter:
            this._progress.loaded += (loaded - data._progress.loaded);
            this._progress.bitrate = this._bitrateTimer.getBitrate(
                now,
                this._progress.loaded,
                data.bitrateInterval
            );
            data._progress.loaded = data.loaded = loaded;
            data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(
                now,
                loaded,
                data.bitrateInterval
            );
            // Trigger a custom progress event with a total data property set
            // to the file size(s) of the current upload and a loaded data
            // property calculated accordingly:
            this._trigger(
                'progress',
                $.Event('progress', {delegatedEvent: e}),
                data
            );
            // Trigger a global progress event for all current file uploads,
            // including ajax calls queued for sequential file uploads:
            this._trigger(
                'progressall',
                $.Event('progressall', {delegatedEvent: e}),
                this._progress
            );
        }
    },

    _initProgressListener: function (options) {
        var that = this,
            xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
        // Accesss to the native XHR object is required to add event listeners
        // for the upload progress event:
        if (xhr.upload) {
            $(xhr.upload).bind('progress', function (e) {
                var oe = e.originalEvent;
                // Make sure the progress event properties get copied over:
                e.lengthComputable = oe.lengthComputable;
                e.loaded = oe.loaded;
                e.total = oe.total;
                that._onProgress(e, options);
            });
            options.xhr = function () {
                return xhr;
            };
        }
    }

这绝对有效,因为该项目维护得很好并且有工作演示。我认为这应该是一个很好的起点。希望它有所帮助。