Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get the correct height property of a div without rendering it to the page?

I'm implementing a Wordpress theme where content slides into the page vertically. To do this, I need to measure the size of the div containing the content without visibly rendering it first. I'm attempting to do all of this without Ajax.

Here's what I've discovered so far:

I can easily load the document, read the size, then hide the div with javascript. Unfortunately there's a very obvious (and unacceptable) flicker because javascript doesn't hide the div fast enough. There's also the issue that if images are placed into the content, I have to wait until they're rendered to get the true size... no bueno.

The other option is to hide the content with the CSS, but if the user doesn't have javascript enabled, they'll just be staring at a blank page.

Which brings me to where I am currently.

I have a piece of javascript that runs immediately after the stylesheet is declared that changes the location of the stylesheet link element and then re-renders the page with a javascript specific stylesheet. This solves the problem of having to hide the content before reading the size.

This was accomplished by positioning the div containing the content absolutely and off the page 9999pixels.

#content {
  position: absolute;
  left: -9999px;
}

At this point, I use jquery to retrieve the height of the content with the following code:

$('#content').height();

The problem is, the number that's coming back is the incorrect size and is much smaller than the actual content. When I change the css to:

#content {
  position: absolute;
  left: 0px;
}

It renders correctly. What gives?? Is there a bug I don't know about? This happens in both Chrome and Firefox.

You can view it for yourself here http://thethechad.com/wordpress

-- UPDATE --------------------------------------------------------------------------

I figured out my problem. The div I was using had no specified width. When I moved it outside the flow of the document, it expanded to fill that gap, shifting the content and reducing the height of the element. I went back into my CSS and hardcoded the width and everything is working fine. I feel really dumb. I'm sure we all have those moments. Thanks so much for the help guys!

like image 511
THEtheChad Avatar asked Aug 22 '11 06:08

THEtheChad


2 Answers

I'm a bit confused by your long explanation, but here's how I measure things without anyone seeing them.

I assign the div a class name I call "measure". Measure has predefined CSS:

.measure {
    position: absolute;    // doesn't affect layout
    visibility: hidden;    // not visible, but normal size
    left: -1000px;         // won't affect scrollbars
    top: -1000px;          // won't affect scrollbars
}

You are then free to get the divs height. Note: it's width may not be the same as it would be in the layout of the page because divs go full width when position: static.

If you want to make sure that the object is never seen, then you can give it an initial class of "measure" in it's original definition and then remove the class later when you want to use the object in the layout of the page.

like image 69
jfriend00 Avatar answered Sep 28 '22 18:09

jfriend00


I'm not sure what is causing your problem, but you might be able to use something like this: http://jsfiddle.net/Paulpro/9YBDB/

<div id="thediv">This is the div</div>
<script type="text/javascript">
    var $thediv = $('#thediv');
    var height = $thediv.height();
    $thediv.hide();
    $thediv.html('Div\'s height is: '+height);
    $thediv.show();
</script>

Were you execute a script to hide the div immediately after the div is rendered, rather than in a script later in your code or on DOMReady etc, so that the flicker doesn't get a chance to occur. However if the user's computer is slow or they are using an older browser the flicker might still appear, I'm not sure. It all depends on if the browsers HTML parser and Javascript engine is fast enough to finish executing $thediv.hide(); before the div is rendered, which I think almost all browsers will be, because rendering is a relatively slow process.

like image 24
Paul Avatar answered Sep 28 '22 16:09

Paul