Jon Derring Jon Derring - 2 months ago 7
jQuery Question

jQuery: Why does .width() sometimes return 0 after inserting elements with .html()?

I am getting some html and inserting it with

.html()
, after which I am trying to get the width of one of newly inserted elements with
.width()
(which has a CSS rule). However sometimes - the width is not picked up, and is returned as 0.

Is it because JS runs "ahead" of newly created elements and their css? I have tried chaining with
.html('...').find('...').width()
but it still sometimes does not work. What's the reason and is there a work around?

Edit: By popular demand, EXAMPLE:

/* ajax.response is:
<div class="boxes">
<div class="box width-A">test 1</div>
<div class="box width-B">test 2</div>
<div class="box width-C">test 3</div>
</div> */

var boxOutput = $('.boxOutput'); /* .boxOutput is already on the page */
boxOutput.html(ajax.response);

// make width of ".boxes" equal to the sum of all ".box"

var boxWidth = 0;
$('.box', boxOutput).each(function(i) {
boxWidth += $(this).width(); /* this is where sometimes width returns 0 */
});
$('.boxes', boxOutput).css('width', boxWidth);


My original code is too long/ugly to copy/paste, but this is a simplified exact thing I am doing (Sorry if there's a silly mistake somewhere, it's too late where I am :P). After getting html back from ajax, putting it into a div, I want to get width of each box (because it might be different), and then use that width. Again, 90% of the time, the width is returned correctly. It's those 10% when sometimes width is 0 :(

Answer

Depends on what browser. Occasionally I find something will break with the synchronous rendering expectations of the javascript runtime and I'll need to get the result on the next tick.

I'd try:

$(elem).html(data);
setTimeout(function(){
    // Get the width here
},0);