我有一个Html输入文件,可以上传图像,并且带有ajax到asp.net MVC控制器,一切正常。
但是我在更新简单的进度条时遇到了麻烦。
这是简单的Html,
<input type="file" multiple="multiple" id="file_upload" />
<br />
<input type="button" id="upload" name="upload" value="Upload" class="btn btn-primary btn-block" />
<br />
<div class="outter">
<div class="inner" id="progress"></div>
</div>
<br />
在我的javascript中,我正在拆分请求,一次上传10张图片,这是它的外观,
<script>
var counter = 0;
$("#upload").click(function () {
var fileUpload = $("#file_upload").get(0);
var files = fileUpload.files;
var devide = devider(files.length);
for (var x = 0; x < devide; x++) {
var fileData = new FormData();
for (var i = 0; i < files.length / devide; i++) {
if (counter < files.length) {
fileData.append(files[counter].name, files[counter]);
counter++;
}
}
$.ajax({
type: "POST",
url: "/Upload/GetFiles",
data: fileData,
cache: false,
contentType: false,
processData: false,
async: false,
success: function (result) {
console.log(result);
},
error: function (xhr, status, error) { console.log('Error:' + error); },
timeout: 0
});
}
});
function devider(number) {
var count = 0;
for (var i = 0; i < number; i+=10) {
count++;
}
return count;
}
</script>
我只需要在每次上传文件时更新<div id="progress">
的宽度,这可能意味着在第二个for循环中。
但我不能,因为它是在一个循环中它没有更新HTML?
P.S。我知道setInterval但我不知道在这种情况下如何实现它??
答案 0 :(得分:1)
这个问题的答案可能是,您无法更新JavaScript循环中的任何HTML!
我不知道为什么它没有被覆盖更多,但我尝试了我在Chrome和Fiddle中尝试过的所有内容,页面上的HTML将无法更新,直到循环结束执行它无关紧要你尝试从循环本身,或者你调用外部函数,再次 HTML将不会重绘,直到循环执行完毕。
然后我发现this post解释了一点
这是一个引用,
JavaScript执行和页面呈现在同一执行中完成 线程,这意味着当你的代码执行时,浏览器会 不要重绘页面。 (即使它正在重绘页面 对于for循环的每次迭代,它都会如此之快 我没有时间看到个别数字。)
所以我不得不放弃for循环以更新HTML,这就是我的JavaScript现在的样子。
<script>
var counter = 0;
var index = 0;
var fileUpload;
var files;
var devide;
var add_width;
var update_width = 0;
var fileData;
var interval;
document.getElementById("file_upload").onchange = function () {
fileUpload = $("#file_upload").get(0);
files = fileUpload.files;
devide = devider(files.length);
add_width = 100 / devide;
$("#progress").css({ "width": "0%", "max-width": "100%" });
}
$("#upload").click(function () {
if (fileUpload) {
$("#outter").css({ "display": "inline-block" });
prepareUpload();
}
})
function prepareUpload() {
fileData = new FormData();
for (var i = 0; i < 10; i++) {
if (counter < files.length) {
fileData.append(files[counter].name, files[counter]);
counter++;
}
}
update_width += add_width;
document.getElementById("progress").style.width = update_width + "%";
document.getElementById("text").innerHTML = Math.round(update_width) + " % Completed";
interval = setInterval(upload, 90);
}
function upload() {
if (index < devide) {
$.ajax({
type: "POST",
url: "/Upload/GetFiles",
data: fileData,
cache: false,
contentType: false,
processData: false,
async: false,
complete: function () {
},
success: function (result) {
if (result < files.length) {
prepareUpload();
} else {
clearInterval(interval);
}
},
error: function (xhr, status, error) { console.log('Error:' + error); },
timeout: 0
});
} else {
clearInterval(interval);
}
index++;
}
function devider(number) {
var count = 0;
for (var i = 0; i < number; i += 10) {
count++;
}
return count;
}
</script>
答案 1 :(得分:0)
我会使用already nicely made progressbar。但这是对你的问题的答案
修改:为您添加了JSFiddle,其中包含一个虚拟进度条:https://jsfiddle.net/strauman/wy7w015e/
您说您希望在文件上传成功后更新进度条。因此,让我们创建一个函数prepare_progressbar
来准备步骤数和一个函数update_progressbar
来更新它。
首先,我们创建变量以包含我们在两个函数中都需要的值:
var width_per_file;
var number_of_files_completed;
var number_of_files_to_upload=0;
现在我们准备&#34;它通过检查上传了多少文件,并初始化变量。
function prepare_progressbar(number_of_files){
var max_progressbar_width=$(window).width();
// Reset the completed-counter
number_of_files_completed=0;
// How much should it increase per file completed?
width_per_file=$(window).width()/number_of_files;
// Set the global number of files
number_of_files_to_upload=number_of_files;
// Make progress bar "hidden"
$("#progress").css({"max-width": "0px"});
}
现在,我们想要创建一个更新进度条的函数。每次ajax完成请求时,我们都希望它调用此函数:
function update_progressbar(){
number_of_files_completed+=1;
var new_progressbar_width=number_of_files_completed*width_per_file;
$("#progress").css({"width":new_progressbar_width+"px", "max-width":new_progressbar_width+"px"});
}
现在唯一剩下的就是将这些函数插入代码中的适当位置。这一切都像这样:
var width_per_file;
var number_of_files_completed;
var number_of_files_to_upload=0;
function prepare_progressbar(number_of_files){
var max_progressbar_width=$(window).width();
// Reset the completed-counter
number_of_files_completed=0;
// How much should it increase per file completed?
width_per_file=$(window).width()/number_of_files;
// Set the global number of files
number_of_files_to_upload=number_of_files;
// Make progress bar "hidden"
$("#progress").css({"max-width": "0px"});
}
function update_progressbar(){
number_of_files_completed+=1;
var new_progressbar_width=number_of_files_completed*width_per_file;
$("#progress").css({"width":new_progressbar_width+"px", "max-width":new_progressbar_width+"px"});
}
var counter = 0;
$("#upload").click(function () {
var fileUpload = $("#file_upload").get(0);
var files = fileUpload.files;
var devide = devider(files.length);
prepare_progressbar(devide);
for (var x = 0; x < devide; x++) {
var fileData = new FormData();
for (var i = 0; i < files.length / devide; i++) {
if (counter < files.length) {
fileData.append(files[counter].name, files[counter]);
counter++;
}
}
$.ajax({
type: "POST",
url: "/Upload/GetFiles",
data: fileData,
cache: false,
contentType: false,
processData: false,
async: false,
// On complete, it will call our update_progressbar
complete: update_progressbar,
success: function (result) {
console.log(result);
},
error: function (xhr, status, error) { console.log('Error:' + error); },
timeout: 0
});
}
});
function devider(number) {
var count = 0;
for (var i = 0; i < number; i+=10) {
count++;
}
return count;
}