reg*_*gie 16 javascript css jquery progress
我有一个进度条,我在许多迭代循环中更新.
https://jsfiddle.net/k29qy0do/32/ (在单击开始按钮之前打开控制台)
var progressbar = {};
$(function () {
progressbar = {
/** initial progress */
progress: 0,
/** maximum width of progressbar */
progress_max: 0,
/** The inner element of the progressbar (filled box). */
$progress_bar: $('#progressbar'),
/** Set the progressbar */
set: function (num) {
if (this.progress_max && num) {
this.progress = num / this.progress_max * 100;
console.log('percent: ' + this.progress + '% - ' + num + '/' + this.progress_max);
this.$progress_bar.width(String(this.progress) + '%');
}
},
fn_wrap: function (num) {
setTimeout(function() {
this.set(num);
}, 0);
}
};
});
$('#start_button').on('click', function () {
var iterations = 1000000000;
progressbar.progress_max = iterations;
var loop = function () {
for (var i = 1; i <= iterations; i++) {
if (iterations % i === 100) {
progressbar.set(i); //only updates the progressbar in the last iteration
//progressbar.fn_wrap(i); //even worse, since no output to the console is produced
}
}
}
//setTimeout(loop, 0);
loop();
});
Run Code Online (Sandbox Code Playgroud)
控制台按预期迭代更新.但是,进度条未更新.
问题是浏览器窗口似乎"挂起",直到循环结束.仅更新控制台,而不是进度条.
我试图在几个地方添加setTimeout,如下所示.但这只会让事情变得更糟,因为我甚至没有让控制台在执行循环时输出进度.
reg*_*gie 11
好的,我在这个问题的答案中找到了一个解决方案:
var i = 0;
(function loop() {
i++;
if (iterations % i === 100) {
progressbar.set(i); //updates the progressbar, even in loop
}
if (i < iterations) {
setTimeout(loop, 0);
}
})();
Run Code Online (Sandbox Code Playgroud)
我的解决方案:https: //jsfiddle.net/ccvs4rer/3/
你真正想要的是一个异步循环,允许浏览器在迭代之间更新DOM.
JSFiddle:http://jsfiddle.net/u5b6gr1w/
function delayedLoop(collection, delay, callback, context) {
context = context || null;
var i = 0,
nextInteration = function() {
if (i === collection.length) {
return;
}
callback.call(context, collection[i], i);
i++;
setTimeout(nextInteration, delay);
};
nextInteration();
}
Run Code Online (Sandbox Code Playgroud)
一些HTML:
<div class="progress-bar"><div style="width: 0"></div></div>
Run Code Online (Sandbox Code Playgroud)
一缕CSS:
.progress-bar {
border: 1px solid black;
background-color: #f0f0f0;
}
.progress-bar div {
background-color: red;
height: 1.25em;
}
Run Code Online (Sandbox Code Playgroud)
还有一些JavaScript将事物连接在一起:
var progressBar = document.querySelector(".progress-bar div"),
items = [1,2,3,4,5,6,7,8,9,10];
delayedLoop(items, 500, function(item, index) {
var width = (item / items.length * 100) + "%";
progressBar.style.width = width;
progressBar.innerHTML = width;
});
Run Code Online (Sandbox Code Playgroud)
让我们把它分解为几步
假设您的问题的目的是了解如何处理进度条而不是样式或标签(加载,请耐心等).让我们只有进度条和开始按钮.
<div id='progressbar-outer' style="">
<div id='progressbar' style=""></div>
</div>
<button id="start_button">Start</button>
Run Code Online (Sandbox Code Playgroud)
让我们让进度条对用户可见
#progressbar-outer {
height:2em;
border:5px solid #000;
width:15em;
}
#progressbar {
width:0%;
background-color:#F00;
height:100%;
}
Run Code Online (Sandbox Code Playgroud)
setTimeout它所属的位置在您的代码中,您已经习惯setTimeout了设置进度条的值.但是,for循环仍然有效.
for (var i = 1; i <= iterations; i++) {
if (iterations % i === 100) {
progressbar.set(i); //only updates the progressbar in the last iteration
//progressbar.fn_wrap(i); //even worse, since no output to the console is produced
//setTimeout(function() {
// progressbar.set(i);
//}, 0);
}
}
Run Code Online (Sandbox Code Playgroud)
使用setTimeout不会影响其余的代码.因此,UI被保留为人质直到循环结束.请尝试以下代码.
$('#start_button').on('click', function () {
var iterations = 100;
progressbar.progress_max = iterations;
var loop = function (value) {
progressbar.set(value);
if (value < iterations) setTimeout(function () {
loop(value + 1)
}, 30);
else $('#progressbar').css('background-color', '#0F0');
}
loop(1);
});
Run Code Online (Sandbox Code Playgroud)
试试这个小提琴:https://jsfiddle.net/Ljc3b6rn/4/
你有什么要做的?你为什么需要它?当您必须等待某些事情完成时,您应该只使用进度条.但是我们不知道你在你的页面上做了什么.
如果要显示ajax上传的进度:
$.ajax({
...
xhr: function() {
var xhr = $.ajaxSettings.xhr();
$(xhr.upload).bind("progress", function(event) {
var e = event.originalEvent;
var percent = 0;
if (e.lengthComputable)
percent = Math.ceil(e.loaded/e.total*100);
$("#progress").width(percent+"%");
});
return xhr;
}
...
});
Run Code Online (Sandbox Code Playgroud)对于图像,您需要ajax调用:
$.ajax({
method: "GET",
url: "http://example.com/path/image.jpg",
xhr: function() {/* see the code above*/ }
...
});
Run Code Online (Sandbox Code Playgroud)要获取上传文件的内容:
var reader = new FileReader();
reader.readAsText(uploadedFile);
$(reader).bind("progress", function(e) {
var percent = 0;
if (e.lengthComputable)
percent = Math.ceil(e.loaded/e.total*100);
$("#progress").css("width", percent+"%");
});
Run Code Online (Sandbox Code Playgroud)对于大量的过程,如数学或附加大量的div将需要10+ secons:
Main.js:
var worker = new Worker("Worker.js");
$(worker).bind("message", function(data) {
$("#progress").width((data*100)+"%");
});
Run Code Online (Sandbox Code Playgroud)
Worker.js:
var total = 43483,
finished = 0,
doStuff = function() {
++finished;
return 1+1;
};
setInterval(function()
{
self.postMessage(finished/total);
}, 100);
for (var i = 0; i < total; ++i)
setTimeout(doStuff, i*10);
Run Code Online (Sandbox Code Playgroud)因为它很好,并且你想告诉用户没有进展,只需为div设置动画:
$("#progress").animate({width: "100%"}, 3000);
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
15413 次 |
| 最近记录: |