frequent
frequent

Reputation: 28513

Why do I need a delay before getting an element's dimensions?

When trying to get elements dimenions during rendering of a page in Jquery, I often find myself having to set timeouts like this:

window.setTimeout(function(){
    console.log("calculate footer height");
    console.log( $('div:jqmData(role="footer")') )
    console.log(  wrap.find('.ui-footer').css("height") )
    },0);

which returns the correct values (in the case 46px), while doing this without the timeout

    console.log("calculate footer height");
    console.log( $('div:jqmData(role="footer")') )
    console.log(  wrap.find('.ui-footer').css("height") )

will return the element, but its width will be 0px

Question:
Why is it like this and more importantly, are there better ways than resorting to setTimeouts like in the example? Please note: I cannot influence rendering of the element, as this is done by Jquery Mobile, so the above has to run from a different "location"

Thanks!

Upvotes: 0

Views: 175

Answers (2)

frequent
frequent

Reputation: 28513

Ok. Haven't found a solution, but I traced the problem down to the following:

  • plugin A gets loaded, initialization prevented, so elements don*t get their dimensions.
  • plugin B gets loaded and initliazed, along the way initializing plugin A.
  • plugin B then tries to get the element dimensions, but as A hasn't fully run through, the elements are still un-enhanced (= no class, no width)

I haven't really found a fix for this, because
a) I need to manually trigger plugin A (= Jquery Mobile), otherwise it will not play nice with requireJS (initializing on mobileinit vs docReady) and
b) my own plugin needs it's event bindings set before Jquery Mobile can init, so I need a manual trigger.

If someone know a workaround for this, I will check as answer.

Thanks for posting.

Upvotes: 0

bukart
bukart

Reputation: 4906

you should respond to the onload event

for example:

$( function() {

    console.log("calculate footer height");
    console.log( $('div:jqmData(role="footer")') );
    console.log(  wrap.find('.ui-footer').css("height") );

} );

your timeout allows the browser to render, so you retrieve correct values. using the onload variant waits until the page is loaded and is triggered then.

often there are some other notations like

$( document ).ready( function() { .... });

of

$().ready( function() { .... });

I prefer

(function($) {
    $( function() { ... } );
} ( jQuery ) );

to ensure $ represents jQuery

Upvotes: 1

Related Questions