4

我已经尝试了所有应该调用回流的方法,但没有发生。我调用我的测试函数 10 次以在我的屏幕上绘制一些元素,并且我在每次迭代中移动该元素。该循环立即执行,最后我得到一张图片,而不是在屏幕上看到元素的移动。

就好像当所有的工作都完成后,屏幕上的回流和绘图被调用了。但我想看每一幅画。

我尝试过的所有事情都没有产生任何结果。唯一有效的是alert(),但我不需要与用户交互。

如果有帮助,我正在使用 webkit 1.2.5。

如果我不够理解,我会尝试更好地解释。

这是我强制重排的代码

 var i = 0;
 for(;i<500;i+=50){
fTestInfo(i);
console.log("Test loop!!! "+i);
 }

我需要的是每次执行 fTestInfo(i) 时在我的屏幕上看到一张图片,但相反,我只看到最终结果。

fTestInfo 取决于 i 它向左移动 i 的值。

4

2 回答 2

1

我看到您正在使用 for 循环,这通常意味着您误解了计时器的工作原理。for 循环是同步执行的,您可能会同时设置所有计时器。

尝试这个:

(function loop(i) {
    if (i >= 500) {
        return;
    }
    document.querySelector("div").style.left = i + "px";
    setTimeout(function() {
        loop(i + 1);
    }, 16);
})(0);

​ 演示http://jsfiddle.net/UCfmF/


我想你的意思是得到一个像.offsetWidth? 这不能保证在屏幕上进行可见的重排,即使您正在执行触发重排的操作,浏览器也可能会等待一段时间(阅读:直到 javascript 执行停止)才能实际尝试在屏幕上绘制任何内容。

这意味着如果您将 1000 个元素附加到文档,它不会触发 1000 次重排。即使您.offsetWidth在每次迭代之间获取。它只会为您计算,但不一定要绘制。

您需要使用计时器移动元素,因为 javascript 执行结束是浏览器清除任何排队的回流时。

请参阅http://dev.opera.com/articles/view/efficient-javascript/?page=3#reflow

如前所述,浏览器可能会为您缓存多个更改,并在所有更改完成后仅重排一次。但是,请注意,对元素进行测量将迫使其回流,因此测量结果将是正确的。更改可能会或可能不会明显重绘,但回流本身仍然必须在幕后发生。

于 2012-08-03T16:28:25.100 回答
0

您需要让浏览器有机会在每次迭代之间进入其事件循环。

用于setTimeout安排绘图的每次迭代:

function scheduledTestInfo(i) {
    setTimeout(function() {
        fTestInfo(i);
    }, i);  // calls each function 50ms apart
}

var i = 0;
for ( ; i < 500 ; i += 50) {
    scheduledTestInfo(i);
}
于 2012-08-06T08:59:05.953 回答