使用JavaScript/jQuery下载文件的进度条
我创建了一个页面,使用JSZip插件将多个文件作为单个zip文件下载。下载文件时,浏览器似乎被挂起,因此我想显示一个进度条,显示下载文件的进度。我不熟悉JavaScript和jQuery,因此无法使用各种网站上的代码。下面是我更愿意在代码中使用的一种方法 我想在文件数量的基础上显示进度。我在每个文件上迭代的每个循环都有一个循环。请帮助我使用上面链接中的代码。非常感谢 以下是我编写的代码:使用JavaScript/jQuery下载文件的进度条,javascript,jquery,jquery-ui,progress-bar,Javascript,Jquery,Jquery Ui,Progress Bar,我创建了一个页面,使用JSZip插件将多个文件作为单个zip文件下载。下载文件时,浏览器似乎被挂起,因此我想显示一个进度条,显示下载文件的进度。我不熟悉JavaScript和jQuery,因此无法使用各种网站上的代码。下面是我更愿意在代码中使用的一种方法 我想在文件数量的基础上显示进度。我在每个文件上迭代的每个循环都有一个循环。请帮助我使用上面链接中的代码。非常感谢 以下是我编写的代码: document.getElementById("downloadZip").addEventListene
document.getElementById("downloadZip").addEventListener("click", function ()
{
sforce.connection.sessionId = '{!$Api.Session_ID}';
var docList = JSON.parse('{!docList}');
var checkedRecords = [];
for(var key in docList)
{
if(docList.hasOwnProperty(key))
{
var isSelected = document.getElementById(docList[key].docRecordId).firstChild.checked;
if(isSelected)
{
checkedRecords.push(docList[key]);
}
}
}
console.log(checkedRecords);
if(checkedRecords.length > 0)
{
document.getElementById("errorMessage").innerHTML = '';
var fileIdList = [];
for(var key in checkedRecords)
{
if(checkedRecords.hasOwnProperty(key))
{
var currentFile = checkedRecords[key];
var fileIdMap = checkedRecords[key].docFileMap;
var fileId;
for(var j in fileIdMap)
{
fileId = fileIdMap[j];
}
fileIdList.push(fileId);
}
}
var zip = new JSZip();
var content = null;
for(var key in fileIdList)
{
if(fileIdList.hasOwnProperty(key))
{
var query = "Select Id,Title,Description,ContentUrl,ContentDocumentId,VersionData,PathOnClient,FileType From ContentVersion WHERE Id = '" + fileIdList[key] + "'";
try
{
var result = sforce.connection.query(query);
var records = result.getArray("records");
var filename = records[0].PathOnClient;
var packCount = 1;
if(filename === '')
{
filename = 'ContentPack_'+packCount;
packCount++;
}
zip.file(filename, records[0].VersionData,{base64: true});
}
catch(err)
{
document.getElementById("errorMessage").innerHTML = 'Content Not Found - ' + err.message;
document.getElementById("errorMessage").style.color = 'red';
}
}
}
content = zip.generate({type: "blob"});
saveAs(content, "myZip.zip");
var sentTo = document.getElementById("ChooseSentTo").value;
updateDocumentation(checkedRecords,sentTo);
}
else
{
document.getElementById("errorMessage").innerHTML = 'Please select a record';
document.getElementById("errorMessage").style.color = 'red';
}
});
不能,这取决于浏览器UI,而不是HTML/DOM界面,请参见注释如果
sforce
来自Salesforce AJAX工具包,则需要使用
我强烈怀疑同步ajax请求的同步方法:浏览器UI将冻结,直到每个请求完成,zip结果就绪。即使使用进度条,如果UI冻结,更新也不会显示
对于异步请求,浏览器将不再冻结:它将能够显示进度条更新
在下面的代码中,fetchDataFromSForces
将sforce
调用转换为延迟的jQuery(您需要jqueryui,因此我假设您的页面上有jQuery)。手动合并异步回调可能会产生难看的代码,而延迟会很好地做到这一点。我没有复制/粘贴生成fileIdList
的块来保持这个答案的可读性,别忘了把它放回去
没有Salesforce服务器,我无法测试此代码,因此可能会出现一些打字错误、小错误等
/**
* Fetch data from the server asynchronously and add files in the zip.
* @param {String} id the id of the ContentVersion to fetch.
* @param {JSZip} zip the zip file to fill in.
* @param {SForce} sforce the Sales Force object.
* @return {jQuery.Deferred} the deferred containing the result.
*/
function fetchDataFromSForces(id, zip, sforce) {
var deferred = jQuery.Deferred();
var query = "Select Id,Title,Description,ContentUrl,ContentDocumentId,VersionData,PathOnClient,FileType From ContentVersion WHERE Id = '" + id + "'";
sforce.connection.query(query, {
onSuccess : function (result) {
var currentProgress = $(".your-progressbar").progressbar("option", "value") || 0;
currentProgress++;
// put the result in the zip
var records = result.getArray("records");
var filename = records[0].PathOnClient;
if(filename === '') {
filename = 'ContentPack_'+currentProgress;
}
zip.file(filename, records[0].VersionData,{base64: true});
// update the progress bar
$(".your-progressbar").progressbar("option", "value", currentProgress);
deferred.resolve(zip);
},
onFailure : function (error) {
deferred.reject(error);
}
});
return deferred;
}
// Create your progress bar first.
$(".your-progressbar").progressbar();
document.getElementById("downloadZip").addEventListener("click", function () {
// ...
// Here, the previous code here to init sforce and get fileIdList
// ...
var zip = new JSZip();
var deferreds = [];
for(var key in fileIdList) {
if(fileIdList.hasOwnProperty(key)) {
deferreds.push(fetchDataFromSForces(fileIdList[key], zip, sforce));
}
}
// re-init the progress bar
$(".your-progressbar").progressbar("option", "value", 0);
$(".your-progressbar").progressbar("option", "max", fileIdList.length);
// join all deferreds into one
$.when.apply($, deferreds).done(function () {
var content = zip.generate({type: "blob"});
saveAs(content, "myZip.zip");
var sentTo = document.getElementById("ChooseSentTo").value;
updateDocumentation(checkedRecords,sentTo);
}).fail(function (err) {
document.getElementById("errorMessage").innerHTML = err.message;
document.getElementById("errorMessage").style.color = 'red';
});
});
向我们展示一下你尝试过什么,我很乐意使用我在问题中提到的jQuery UI插件。对于Chrome来说,现在访问下载的唯一方法是通过一个扩展,我想你没有得到我想要的。我想在for循环中使用进度条代码,并在for循环的基础上增加进度(循环执行的次数)。我已经在我的问题中提供了上面进度条的链接。你好,大卫,谢谢你的回复。是的,使用ajax调用的异步语法是有意义的。我也尝试过你在我的页面上使用进度条的方法。但是我不能用它。Progressbar方法未定义。尽管JS库在那里。请帮助我理解这段代码,以便我可以在for循环中使用这段代码并相应地提高进度。$(function(){var progressbar=$(“#progressbar-5”);progressLabel=$(“.progressLabel”);$(“#progressbar-5”)。progressbar({value:false,change:function(){progressLabel.text(progressbar.progressbar(“value”)+“%”;},complete:function(){progressLabel.text(“加载完成!”;}}});function progress(){var val=progressbar.progressbar(“值”)| | 0;progressbar.progressbar(“值”,val+1);if(val<99){setTimeout(progress,100)}}}setTimeout(progress,3000)});您上一篇评论中的代码起作用了:我刚刚添加了jQuery(js)和jQueryUI(js,css)。如果你仍然有这个问题,你能创建一个不起作用的JSFIDLE代码吗?嗨,David,谢谢你的回答,它对理解我面临的问题有很大帮助,我能解决它。