这已经困扰了我多年,所以我创建了一个测试jsFiddle来说明情况。
代码如下:
$('#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);
}
});
现在,我原本以为背景颜色应该首先改变,然后开始创建孩子。但是,颜色不会改变,直到for
循环结束。
但是,如果您使用setTimeout
延迟代替for
循环,则情况并非如此。
var timeoutID = window.setTimeout(function () {
$('#test').css('background', 'blue');
}, 2000);
在setTimeout
情况下,您会在2秒后看到瞬间变红,然后变为蓝色。编辑:这是第二种情况的fiddle。
为什么我的第一个小提琴做它做的事情?它适用于许多其他情况,特别是关于AJAX。
答案 0 :(得分:3)
在整个函数执行之前,浏览器不会触发重绘。
你可以在调用for循环之前重新绘制它,方法是将for包装在一个超时为零的setTimeout中,如下所示:
$('#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);
});
答案 1 :(得分:1)
javascript中只有1个主线程。
循环阻止所有事情发生,排队setTimeouts()
或背景重绘等事情。
不同之处在于,setTimeout()
不需要繁重的计算,因为它只是一个堆栈,因此您的100,000次迭代循环更快完成,并允许执行下一个排队函数(在本例中为重绘)。
答案 2 :(得分:0)
我尝试过简单修改http://jsfiddle.net/Pbgz3/12/。在循环运行之前,颜色确实发生了变化。检查我是否减少了循环迭代。