I have a webpage that embeds the HTML provided through AJAX. I donβt know, a priori, the size of the content, but I need to place the content on the page depending on its size. Here is a simple approach that does not work:
- Set the opacity of the parent container to 0.
- Paste the content into the DOM.
- Measure the dimensions, for example.
$el.outerWidth(true) . - Place content based on these sizes.
- Set the transparency of the parent container (back) to 1.0.
The problem with this approach is that the content is quite complex and includes images. When outerWidth() is called, the browser has not finished repainting the screen so that the returned sizes are not accurate. (Interestingly, in my case, the initial sizes are always significantly larger than the final values, and not 0, as I might expect.)
I can reduce the problem by setting a timer between steps 2 and 3, but no matter how long I take the timer, some system will probably have some kind of browser that will exceed it. And if I make the timer long enough to cover most cases, it will punish users with faster systems by introducing unnecessary delays. Although some of the answers below suggest that setTimeout(fn, 0) is sufficient, I found that it is not. I measured the drawing time to 60 ms on a MacBook Air in 2012, and one answer below offers 500 ms.
It seems that Mozilla once had an onPaint event that could solve my problem ... if it still exists, and if other browsers accepted it. (Neither one nor the other). Mutation observers do not seem to take into account drawing time when reporting changes in elements.
Decisions or comments are greatly appreciated. As noted below, this has been asked before, but most of the questions are at least a year old, and I am desperate to try again.
Related questions, which, unfortunately, do not give a workable answer
Update: Well, it seems like this is just not a general solution to this problem. In my specific case, I found a property that will change reliably after loading the contents and layout. Poll JavaScript to change this property. Not at all elegant, but it was the best option I could find.