Why are CSS animations and transitions blocked by JavaScript?
The selected answer is a bit out of date. As of today on OSX safari, firefox, and chrome all run css animations in separate thread from javascript.
CSS transitions blocked by JavaScript
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();
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.
Using CSS animation while javascript computes
CSS3 animations do not get blocked by Javascript unless there is some intense processing going on (in which case you could get stutters).
If you are triggering them during the load I could see them getting delayed until they get to that portion of the script.
One way around this is to setTimeouts at the very beginning of the script to trigger animation changes at certain times.
Another (perhaps better) option would be to use keyframes. Make sure to call this before the loading begins. http://dev.w3.org/csswg/css3-animations/#keyframes
Why blocking event loop does not block css animation?
This is because implementers are encouraged by the specs to not follow the specs...
alert()
calls the pause algorithm, which should block the current task and cause the event loop to have nothing to do anymore than waiting for the "condition goal is met".
Though, this page also has a big warning paragraph stating,
Pausing is highly detrimental to the user experience, especially in scenarios where a single event loop is shared among multiple documents. User agents are encouraged to experiment with alternatives to pausing, such as spinning the event loop or even simply proceeding without any kind of suspended execution at all, insofar as it is possible to do so while preserving compatibility with existing content. This specification will happily change if a less-drastic alternative is discovered to be web-compatible.
So your UA certainly followed the advice to experiment with a spin-the-event-loop alternative, which allows for other tasks to still run, even though the one that called alert()
has been paused.
CSS animation is blocked
besides the showed styles, the CSS on your page also contains
.headroom--unpinned {
display: none
}
wich you don't and can't transition, that interferes with your effect
CSS transition doesn't work with jQuery's .toggleClass()
transition
doesn't work for display
. try to change display:none
and display:block
to opacity:0
and opacity:1
Related Topics
Html:Draw Table Using Innerhtml
How to Call a Js Function Using Onclick Event
How to Detect Support for the HTML5 "Download" Attribute
How to Get a Floating Footer to Stick to the Bottom of the Viewport in Ie 6
Transitionend Event Fires Twice
How to Have Tabs Without JavaScript
Changed Id Not Being Found by Jquery
JSON Datetime Between Python and JavaScript
Add Property to an Array of Objects
How to Reload Page Every 5 Seconds
How to Reach the Element Itself Inside Jquery's 'Val'
How to Resize HTML Canvas Element
JavaScript Error Null Is Not an Object
How to Stop User from Printing Webpages? Using JavaScript or Jquery
Jquery Mobile Prevent Scroll-To-Top Before Page Transition
IE8 V8 Not Changing Class for a Dom Element Despite Js Function Changing the Element Attribute