3

Given this code:

$('#foo').css('height', '100px'); // or any other change to the DOM
console.log('done!');

When the 2nd statement executes, is it safe to assume that the reflow is complete?

Follow on question: if you replaced the second line with this, does it change the answer?

window.setTimeout('console.log("done");', 1);

I hope my underlying question is clear. Thanks a lot for any input.

GregT
  • 1,300
  • 3
  • 16
  • 25
  • See http://stackoverflow.com/questions/510213/when-does-reflow-happen-in-a-dom-environment – bfavaretto Apr 01 '13 at 22:16
  • That post talks about the triggering of a reflow but doesn't appear to deal with the question of when the surrounding script executes in relation to the reflow completing. – GregT Apr 01 '13 at 22:20

2 Answers2

3

Browsers usually queue DOM modifications that require a reflow/repaint, to avoid performing that expensive operation multiple times. There are exceptions to that, however, as you can see in this Q&A: When does reflow happen in a DOM environment?.

Considering the code you posted, and assuming the console will log the output synchronously*, the answer to your first question is no. If you just change the height of an element, the browser will typically finish running all other synchronous code before performing the reflow/repaint operation. But, as the answers on the link above says, some actions do trigger an immediate reflow, so it's not possible to answer the "or any other change to the DOM" part of your question.

Considering the same assumptions above, the answer to your second question would be yes. The string "done" will be logged to the console in the next tick of the browser's event loop, so it's safe to assume that's after the reflow.

Usually you don't have to worry about that kind of browser behavior, unless you're optimizing code for performance, and trying to avoid reflows.

* Sometimes the console outputs later than expected; unfortunately I couldn't find a good link about that.

Community
  • 1
  • 1
bfavaretto
  • 71,580
  • 16
  • 111
  • 150
  • Thanks for the reply. We have code where we measure the size of things after changing CSS and have suspicion that it's flaky because the size may or may not reflect the most recent reflow. – GregT Apr 01 '13 at 23:09
  • So try moving the problematic code into a setTimeout call, as in your example. If it works, likely it was indeed an issue with a reflow not being forced. – bfavaretto Apr 02 '13 at 00:28
  • This should be the accepted answer. The essential part is "Considering the code you posted, and assuming the console will log the output synchronously*, the answer to your first question is no". Furthermore, it provides important background info. – Dr. Jan-Philip Gehrcke Sep 01 '13 at 20:50
-1

The .css() method is not asynchronous, thus you can safely assume that any statements after it will execute as you expect.

$('#foo').css('height', '100px');
console.log($('#foo').css('height')); // will log '100px'
Brad M
  • 7,857
  • 1
  • 23
  • 40
  • Thanks for the quick reply. Is this generally true of all DOM manipulation via JavaScript, eg. inserting elements without using jQuery? Cheers. – GregT Apr 01 '13 at 22:18
  • 1
    It depends on the method. Look at the jQuery documentation; if a method has a callback function, then you can assume it executes asynchronously. – Brad M Apr 01 '13 at 22:22
  • 1
    This is a delicate topic. This answer is overgeneralized and provides too little background about how the browsers really deal with the statements as given in the example. When dealing with e.g. CSS transitions, the height might not immediately be 100px, see http://jsfiddle.net/HJC7j/ – Dr. Jan-Philip Gehrcke Sep 01 '13 at 20:50
  • Whilst the jQuery function is not asynchronous, the DOM reflow is. Please consider changing your accepted answer @GregT as this one is wrong :( – Bill Dec 02 '15 at 15:53