1

这一直困扰着我很长时间,所以我创建了一个测试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 秒后看到蓝色。编辑:这是第二种情况的小提琴

为什么我的第一个小提琴会做它做的事情?它适用于许多其他情况,尤其是关于 AJAX。

4

3 回答 3

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);
});
于 2012-07-11T05:16:28.097 回答
1

您在 javascript 中只有 1 个主线程。

循环阻止一切发生,例如排队setTimeouts()或背景重绘。

不同之处在于,setTimeout()不需要大量计算,因为它只是一个堆栈,因此您的 100,000 次迭代循环完成得更快,并允许执行下一个排队的函数(在本例中为重绘)。

于 2012-07-11T05:24:02.797 回答
0

我尝试过对其进行简单修改http://jsfiddle.net/Pbgz3/12/。颜色确实在循环运行之前发生了变化。检查我是否减少了循环迭代。

于 2012-07-11T05:16:26.807 回答