我正在尝试为我的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
答案 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功能。
此对象的属性没有很好地记录,我不确定它是否仍然支持您尝试在代码中利用的upload
和progress
功能。
即使在该博客的评论中,人们建议使用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;
};
}
}
这绝对有效,因为该项目维护得很好并且有工作演示。我认为这应该是一个很好的起点。希望它有所帮助。