我正在尝试在JavaScript的非常密集期间创建一个加载栏,其中构建并填充了一些相当重的3d数组。在用户单击按钮之前,此加载栏必须保持为空。
发生冻结是否我正在使用-webkit-transition
(此应用可以是chrome独家,在我的情况下不需要跨浏览器。)
寻求简洁我已经建立了这样的吧......
<div id="loader">
<div id="thumb">
</div>
</div>
...然后在我的主for
循环的各个阶段尝试增加该栏:
for(i = 0; i < 5 ; i++){
document.getElementById('thumb').style.width = i*25 + '%';
//More Code
}
问题是在JavaScript完成之前,所有内容都会冻结。 我在Stack Overflow上发现了类似的问题Using CSS animation while javascript computes,并在评论中找到并考虑和/或尝试了以下内容:
网络工作者
不要认为它会起作用,因为我的脚本正在填充一个数组,其中包含根据this site无法正常工作的对象和构造函数
的jQuery
不是一个选项,我不能在我的应用程序中使用外部库 - 无论如何,仅为加载栏导入整个库似乎有点像矫枉过正......
关键帧
这很有希望,我尝试了,但最后它也冻结了,所以没有快乐
timeOut()
Š
考虑到这一点,但由于加载栏的目的是减少挫折感,增加等待时间似乎适得其反
我很高兴在这个阶段有任何增量栏,即使它不顺利!我很确定这是一个不仅仅是我的问题 - 也许有人有一个有趣的解决方案?
PS:我发布这个作为一个新问题,而不是添加到引用的问题,因为我特别寻求JavaScript(而不是jQuery)的帮助,并希望我能使用转换(!宽度上的动画。
答案 0 :(得分:5)
有些人已经提到你应该使用超时。这是合适的方法,它会让浏览器有时间“呼吸”并在任务中间渲染你的进度条。
您必须将代码拆分为异步工作。说你现在有类似的东西:
function doAllTheWork() {
for(var i = 0; i < reallyBigNumberOfIterations; i++) {
processorIntensiveTask(i);
}
}
然后你需要把它变成这样的东西:
var i = 0;
function doSomeWork() {
var startTime = Date.now();
while(i < reallyBigNumberOfIterations && (Date.now() - startTime) < 30) {
processorIntensiveTask(i);
i++;
}
if(i < reallyBigNumberOfIterations) {
// Here you update the progress bar
incrementBar(i / reallyBigNumberOfIterations);
// Schedule a timeout to continue working on the heavy task
setTimeout(doSomeWork, 50);
}
else {
taskFinished();
}
}
function incrementBar(fraction) {
console.log(Math.round(fraction * 100) + ' percent done');
}
function taskFinished() { console.log('Done!'); }
doSomeWork();
注意表达式(Date.now() - startTime) < 30
。这意味着循环将在30毫秒的范围内尽可能多地完成。你可以把这个数字做得更大,但是从用户的角度来看,任何超过100毫秒(基本上每秒10帧)的东西都会开始变得迟钝。
使用这种方法而不是同步版本,整个任务可能会花费更长的时间。但是,根据用户的体验,指示某事正在发生的事情比无限期等待更好,而没有似乎正在发生 - 即使后者的等待时间更短。 / p>
答案 1 :(得分:1)
你是否尝试过更简单的功能,让我们说:
伪:
Function increment_bar(amount = 10)
{
document.getElementById('thumb').style.width = i*amount + '%';
}
然后,无论你在哪里进行处理工作,只需每隔x秒调用一次该函数,或者每当你在处理过程中遇到某个点时(让我们说10-20%完成?)
伪:
{
Doing_work_here;
increment_bar(25);
LOOP
}