Getting Accurate Dimensions for a newly-created DOM object
Asked Answered
M

2

6

I'm creating DOM elements dynamically (more specifically, using jQuery to create a DIV containing some text with css "width:auto", and using a "font-face" font, in the page OnLoad event) but find that the width of the div is not the expected size (specifically, the width is wrong) immediately after I create it and add it to the DOM tree. I need to know the width/height of the element because I will be doing some dynamic layout on it.

As a workaround, I use the following code after creating the elements:

SetTimeout(complete_layout,100)

By delaying the completion of my layout with this extra timeout, everything works perfectly, with all element sizes exactly as expected (In the latest Chrome on Ubuntu Linux)

However, this klugey timer delay offends my sensibilities and is clearly unsafe... Is there any way to force accurate dimension calculations with a specific command? Or, is there an event I can register that will fire only once all the DOM elements have been correctly sized, after new dynamic elements are created? (I am picturing something like the IMG onload event, which allows you to figure out the proper dimensions of an image once it has been loaded)

tl;dr: Is there a guarantee as to when the width of a newly-created DOM object will be accurate?

Thanks for your help!

Mccarley answered 8/1, 2011 at 20:54 Comment(3)
Are you doing other DOM manipulation after you add that DIV into the DOM?Syndic
No, I just do $("#foo").append($("<div class='bar'>...</div>")) and have css that should determine the proper sizing of the DIV. Immediately, if I check the width it is wrong. However, if I delay 100ms with a timer, it is correct. I can't find any info online that describes when the dimensions of a newly created DOM object are guaranteed to be accurate.Mccarley
You will have better luck getting good answers if you post a little code reduction that reproduces the issue. jsbin.com and jsfiddle.net are handy for this. You may even solve the problem yourself if you do.Keyte
P
3

How are you trying to get the width? .css("width"), or .width(),

You should be using .width(), as .css("width') wont return anything except auto (if no width was specified in some style)

$("#foo").width();

It should give width even after immediate appending.

Publius answered 8/1, 2011 at 21:29 Comment(3)
I am using $('#foo').outerWidth(). After doing some more researching online, I think you are right that "It should give width even after immediate appending". This suggests to me that I'm probably dealing with a Chrome bug that I will have to research further.Mccarley
@Mccarley I'm having the same problem three years on with Firefox, I don't think it's a chrome bug. Identical elements are giving different, incorrect widths and heights immediately after being appended and styled by jQuery. Did you find any solution?Psephology
Now I just precalculate text extents for individual font characters offline and then estimate widths by calculating them with my own javascript code without using the DOM at all. Makes life much easier, if you can accept a few pixels of error (due to oversimplification of the browser's text kerning calculations.)Mccarley
A
0

You could get the width by getting the width of the element you add the new div to. Since the width of the new div is set to auto they should be the same.

This will however not work for the height.

Arvizu answered 8/1, 2011 at 21:15 Comment(5)
Not sure I understand what you're saying... The new DIV has text in it, which will determine the width of the new DIV- This is the width I'm trying to figure out. I'm not sure how the width of the parent DIV figures in to the issue, but maybe I my question wasn't clear enough :)Mccarley
If no width style is set to the DIV, then it defaults to auto which in turn expands as far as the parents width.Publius
Maybe I'm wrong or am missing something, but I thought the width of a DIV with "width:auto" will be equal to the length of its own content, not the width of the parent. The only exception is if the parent has a width that is smaller that the width of the content of the div (In my case, the content is just a single word and much smaller than the width of the parent)Mccarley
Sorry to say it, but you are indeed wrong in your assumption. Should probably use a span element (or set display:inline). A span only has the width of the content containing it. Though I'm not sure what will happen if you have multi-line content.Arvizu
@Mccarley as Gerben mentions you're assumption is wrong because of the type of element it is. DIV's have a css display style of block by default. Block style makes the element fill to the parents width (minus any padding widths). inline and inline-block styles are the ones that expand, width wise, to their content. And here again Gerben mentions a using a span, and spans by default have an inline display style so it's width expands on contentPublius

© 2022 - 2024 — McMap. All rights reserved.