由JavaScript阻止的CSS转换

时间:2012-11-19 20:42:50

标签: javascript css-transitions

我正在尝试在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)的帮助,并希望我能使用转换(!宽度上的动画。

2 个答案:

答案 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
}