JavaScript阻止CSS过渡

问题描述:

我正在尝试在JavaScript的非常密集时期创建一个加载栏,其中会构建并填充一些相当重的3d数组。在用户单击按钮之前,此加载栏需要保持为空。

I am trying to create a loading bar during a very intensive period of JavaScript where some pretty heavy 3d arrays are built and filled. This loading bar needs to remain empty until the user clicks a button.

冻结发生是否我正在使用 -webkit-transition (此应用程序可以是chrome独占,在我的情况下不需要跨浏览器。)

The freezing occurs whether or not I'm using -webkit-transition (This app can be chrome exclusive, cross browser is not necessary in my case).

寻求简单性,我已经建立了这样的酒吧...

Seeking simplicity I've built my bar like this...

<div id="loader">
    <div id="thumb">
    </div>
</div>

...然后在我的主要 for 循环:

... and then sought to increment that bar at various stages of my main for loop:

for(i = 0; i < 5 ; i++){
    document.getElementById('thumb').style.width = i*25 + '%';
    //More Code
}

问题在于,所有内容都会冻结直到JavaScript完成。
我在堆栈溢出中发现了类似的问题,,并在找到并考虑和/或尝试了以下注释的注释中使用CSS动画:

Problem is that everything freezes until the JavaScript finishes. I found a similar question on Stack Overflow, Using CSS animation while javascript computes, and in the comments found and considered and/or tried the following:


  • Web Workers

  • Web Workers

别以为它会起作用,因为我的脚本正在用对象和构造函数填充数组,其中包含根据此网站不会工作

Don't think it'll work since my script is filling an array with objects and constructors containing functions which according to this site isn't going to work

jQuery

不是一种选择,我无法在应用中使用外部库-无论如何,仅仅为加载条导入整个库似乎有点过分...

Not an option, I can't use external libraries in my app - in any case, importing a whole library just for a loading bar seems kind of like overkill...

关键帧

这很有希望,我尝试了一下,但最后它也冻结了,所以没有喜悦

This was promising and I tried it, but in the end it freezes also, so no joy

timeOut() s

对此有所考虑,但是由于加载栏的目的是减少沮丧感,因此增加等待时间似乎适得其反

Thought about this, but since the point of the loading bar is to reduce frustration, increasing the waiting time seems counter-productive

我很乐意在此阶段增加任何条,即使它不平滑!我很确定这是一个不仅仅是我一个人的问题-也许有人有一个有趣的解决方案?

I'd be happy to have any incrementation of the bar at this stage, even if it's not smooth! I'm pretty sure this is a problem that has struck more than just me - maybe someone has an interesting solution?

PS:我将其发布为一个新问题,而不是添加到所引用的问题,因为我正在特别寻求JavaScript(而非jQuery)的帮助,并且希望我可以使用宽度上的过渡(!= animation)来获得它。

已经有人提到您应该使用超时。那是适当的方法,因为它将使浏览器有时间呼吸并在进度条中执行任务。

Some people already mentioned that you should use timeouts. That's the appropriate approach, bc it'll give the browser time to "breathe" and render your progress bar mid-task.

您必须拆分代码才能工作异步地。假设您当前有这样的东西:

You have to split your code up to work asynchronously. Say you currently have something like this:

function doAllTheWork() {
  for(var i = 0; i < reallyBigNumberOfIterations; i++) {
    processorIntensiveTask(i);
  }
}

然后您需要将其转换为以下内容:

Then you need to turn it into something like this:

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帧)的速度都将开始变得缓慢。

Note the expression (Date.now() - startTime) < 30. That means the loop will get as much done as it can in the span of 30 milliseconds. You can make this number bigger, but anything over 100ms (essentially 10 frames-per-second) is going to start feeling sluggish from the user's point of view.

的确,与同步版本相比,使用这种方法需要花费更长的时间来完成整个任务。但是,从用户的经验来看,暗示某事正在发生要比无限期地等待而什么似乎正在发生要好-即使后者的等待时间较短。

It may be true that the overall task is going to take somewhat longer using this approach as opposed to the synchronous version. However, from the user's experience, having an indication that something is happening is better than waiting indefinitely while nothing seems to be happening – even if the latter wait time is shorter.