Shakal187
Shakal187

Reputation: 173

How to force a reflow in javascript in webkit 1.2.5

I've tried everything that is supposed to invoke a reflow but that isn't happening. I'm calling my test function 10 times to draw some element on my screen and I move that element through each iteration. That loop is executed immediately and in the end I get one picture instead of seeing the movement of the element on the screen.

It's as if when all work is done, reflow and drawing on the screen is invoked. But i want to see each drawing.

All the things I've tried didn't give any results. The only thing that works is alert(), but i don't need an interaction with user.

I'm using an webkit 1.2.5 if that helps.

If I'm not understandable enough I will try to explain better.

This the code I'm forcing to reflow

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

The thing I nedd is to see a picture on my screen each time fTestInfo(i) is executed but instead, i only see the ending result.

fTestInfo depends on i it moves in left by the value of i.

Upvotes: 4

Views: 1294

Answers (2)

Esailija
Esailija

Reputation: 140230

I see you are using a for loop which typically means you misunderstand how timers work. The for loop is synchronously executed and you are probably setting all the timers at once.

Try this:

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

​ demo http://jsfiddle.net/UCfmF/


I suppose you mean getting a value like .offsetWidth? This is not guaranteed to make a visible reflow on the screen, browsers may wait for some time (read: until javascript execution stops) before actually attempting to paint anything on the screen even if you are doing actions that trigger reflows.

This means that if you append 1000 elements to the document, it will not trigger 1000 reflows. Even if you fetch .offsetWidth in between each iteration. It will just be calculated for you but not necessarily painted.

You need to move the elements with a timer as the end of javascript execution is when browsers flush out any queued reflows.

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

As stated earlier, the browser may cache several changes for you, and reflow only once when those changes have all been made. However, note that taking measurements of the element will force it to reflow, so that the measurements will be correct. The changes may or may not not be visibly repainted, but the reflow itself still has to happen behind the scenes.

Upvotes: 1

Alnitak
Alnitak

Reputation: 339836

You need to give the browser the opportunity to enter its event loop between each iteration.

Use setTimeout to schedule each iteration of the drawing:

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

var i = 0;
for ( ; i < 500 ; i += 50) {
    scheduledTestInfo(i);
}

Upvotes: 0

Related Questions