Reputation: 6025
This has been bugging me for ages, and so I've created a test jsFiddle to illustrate the situation.
The code is as follows:
$('#test').on('click', function() {
$(this).css('background', 'red');
for (var i = 1; i < 100000; i++) {
var el = document.createElement("div");
el.innerHTML = "Another";
document.getElementById("container").appendChild(el);
}
});
Now, I would have thought that the background color should change first, and then the creation of the children would begin. The color doesn't change, though, until after the for
loop has finished.
This is not the case, however, if you put a setTimeout
delay in place of the for
loop.
var timeoutID = window.setTimeout(function () {
$('#test').css('background', 'blue');
}, 2000);
In the setTimeout
case, you see instantaneous red and then blue 2 seconds later. EDIT: Here's the fiddle for the second case.
Why does my first fiddle do what it does? It applies in so many other situations, particularly regarding AJAX.
Upvotes: 1
Views: 98
Reputation: 10907
You only have 1 main thread in javascript.
Loops block everything from happening, things like queued setTimeouts()
or background repaints.
The difference is, setTimeout()
doesn't require heavy computations, because it's just a stack, so your 100,000 iterations loops finishes quicker, and allows the next queued function (in this case, the repaint) to execute.
Upvotes: 1
Reputation: 473
The browser isn't triggering a repaint until the whole of the function has executed.
You can make it repaint before calling the for loop by wrapping the for in a setTimeout with a timeout of zero, like so:
$('#test').on('click', function() {
$(this).css('background', 'red');
setTimeout(function(){
for (var i = 1; i < 100000; i++) {
var el = document.createElement("div");
el.innerHTML = "Another";
document.getElementById("container").appendChild(el);
}
}, 0);
});
Upvotes: 3
Reputation: 957
I have tried a simple modification of it http://jsfiddle.net/Pbgz3/12/ . The color indeed changes before the loop is run. To check that i have decreased the looping iterations.
Upvotes: 0