Obtener dimensiones precisas para un objeto DOM recién creado

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) inmediatamente 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?

Gracias por su ayuda!

preguntado el 08 de enero de 11 a las 20:01

Are you doing other DOM manipulation after you add that DIV into the DOM? -

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. -

You will have better luck getting good answers if you post a little code reduction that reproduces the issue. jsbin.com y jsfiddle.net are handy for this. You may even solve the problem yourself if you do. -

2 Respuestas

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.

Respondido el 09 de enero de 11 a las 00:01

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. - drcode

@drcode 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? - user56reinstatemonica8

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.) - drcode

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.

Respondido el 09 de enero de 11 a las 00:01

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 :) - drcode

If no width style is set to the DIV, then it defaults to auto which in turn expands as far as the parents width. - Patrick Evans

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 adueñarnos 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) - drcode

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. - Gerben

@drcode 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 content - Patrick Evans

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.