setTimeout不能强制浏览器立即重绘

时间:2014-08-03 03:47:32

标签: javascript ajax internet-explorer google-chrome settimeout

我想用setTimeout逐一突出显示一些单词。它适用于Chrome和Firefox(即使没有setTimeout,也可以在Firefox中使用,只需ajax就可以逐一进行突出显示)。但它在IE或Safari中不起作用,它们仍然在JS代码完成后显示所有亮点。 JS代码是:

for(var k=0;k<MAX;k++) {            
    (function (_k) {                
        setTimeout( function() {
        $.ajax({
            //do something
            success: function(data, textStatus, jqXHR) {  
                //using wrap <span> tag to highlight words according to ajax return data
            }
        }); } ,2000);
    }) (k);
}

我只是希望浏览器重新绘制页面并立即显示突出显示,问题是什么?非常感谢!

3 个答案:

答案 0 :(得分:0)

你在做什么是“推迟一切”。就像

// Say you have these values
var a = 1, b = 2, c = 3;

// The loop is technically doing
a+=1, b+=1, c+=1;

// And the end effect is the same. They're still in line.
a == 2;
b == 3;
c == 4;

您可能希望对每个项目执行setInterval,这样每个标记都会相互延迟。

var timer = setInterval(function(){

  // do what you need to do here as if in the loop

  if(k >= MAX) clearInterval(timer);
});

另外,你不能指望“立竿见影”。看到你有一个AJAX呼叫,如果网络窒息,那么“立即”是不可能的。

答案 1 :(得分:0)

在你的代码中,你跳过了构成或破坏重绘的确切行(或显示延迟重绘是一个实际问题还是我们正在寻找更深层次的东西)。

element.offsetWidth;这样的显式几何访问通常有助于解决不需要的渲染优化问题,如果是这种情况的话。

答案 2 :(得分:0)

setTimeout()$.ajax()启动异步进程,然后立即继续到下一行。所以你的for循环将在任何超时运行之前,并且在任何ajax成功回调运行之前完成,并且所有超时都被安排在循环结束后2000毫秒运行,即更多或者更少同时。

如果你希望每一个在前一个之后两秒发生,那么要么在开始下一个之前等待先前的ajax请求完成,要么通过将延迟乘以循环计数器来增加每个后续超时的超时延迟:

for(var k=0;k<MAX;k++) {            
    (function (_k) {                
        setTimeout( function() {
          $.ajax({
            //do something
            success: function(data, textStatus, jqXHR) {  
                //using wrap <span> tag to highlight words according to ajax return data
            }
          });
        } , 2000 * k);     // <--- this line is the only change
    }) (k);
}

那样第一次超时是0ms,第二次是2000ms,第三次是4000ms等。

演示:http://jsfiddle.net/gsRL7/