469,275 Members | 1,806 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,275 developers. It's quick & easy.

Determining the height and width of a <div> dynamically

Frinavale
9,735 Expert Mod 8TB
Hi there!

I've created a "message" box that consists of a <div> with a bunch of information in it and some buttons (which could be "ok", "yes", "no", "cancel"...). It's dynamically created with some .NET code on the server.

Because the message information that is within this <div> is dynamic, it can be several lines long...also the message box <div> can be variable widths wide as well. Therefore, I need a Dependable way to dynamically retrieve the width and height of the <div> in order to properly center it in the middle of the browser.

I have used:
Expand|Select|Wrap|Line Numbers
  1. var panelHeight = document.getElementById(nameOfMessageBoxWindow).clientHeight;
  2. var panelWidth = document.getElementById(nameOfMessageBoxWindow).clientWidth;
  3.  
However this code only seems to work in certain circumstances, and others doesn't work at all (using firebug I discovered that these two values were always 0 for some weird reason).

In order to find the width of the <div>, I set the <div>'s style width dynamically with my .NET code and then used the following code:
Expand|Select|Wrap|Line Numbers
  1. var styleWidth = panel.style.width;
  2. var panelWidth = Number(styleWidth.replace(/px/,""));
  3.  
This works, however it feels like a bit of a "workaround" to me. Also, this solution doesn't help me find the height of the <div>.

Does anyone know what might be the cause to the element.clientWidth to always be 0?
Does anyone know of another way to dynamically determine the height and width of the <div>?

Thanks for your time,

-Frinny
Mar 28 '08 #1
13 5805
gits
5,390 Expert Mod 4TB
hi frinny,

have a look whether this thread helps ... and here is another link ;)

kind regards
Mar 28 '08 #2
Frinavale
9,735 Expert Mod 8TB
hi frinny,

have a look whether this thread helps ... and here is another link ;)

kind regards
Thanks Gits,
I'm looking into the offsetHeight and offsetWidth now.
I think I've tried this before, I'll get back to you to let you know if it helps.


-Frinny
Mar 28 '08 #3
Frinavale
9,735 Expert Mod 8TB
Thanks Gits,
I'm looking into the offsetHeight and offsetWidth now.
I think I've tried this before, I'll get back to you to let you know if it helps.


-Frinny
The offsetHeight and offsetWidth did not work.
Mar 28 '08 #4
gits
5,390 Expert Mod 4TB
i just tested it in IE6 and FF and it worked without problems ... may be you could post a html-example that demonstrates your problem?

kind regards
Mar 28 '08 #5
Frinavale
9,735 Expert Mod 8TB
i just tested it in IE6 and FF and it worked without problems ... may be you could post a html-example that demonstrates your problem?

kind regards
It's really complicated because of the auto generated stuff that the .NET code does.

Basically I have a control that handles uploading of pictures, if the picture is not uploaded properly a message window is supposed to be displayed in the middle of the page. This is the message window that does not center (because the clientHeight and offsetHeight of this <div> are 0).

The control that handles the uploading of the pictures is buried deep within nested <divs>.

I have other message box <div> windows as well on the page (which are also buried within other <div>s but not so deep) and they center properly.

I'll see what I can figure out to try and easily show you the problem....

The worst part is that it works in most cases, it's just this deeply buried message box that's the problem.

-Frinny
Mar 28 '08 #6
Try these two functions out:
http://www.matts411.com/webdev/width_and_height_getter_functions_for_html_element s

Just wrote them. Should work but have yet to do enough testing to prove that they work 100% of the time.
Mar 28 '08 #7
Frinavale
9,735 Expert Mod 8TB
Try these two functions out:
http://www.matts411.com/webdev/width..._html_elements

Just wrote them. Should work but have yet to do enough testing to prove that they work 100% of the time.
In the following code you check to see if the element (in my case the <div> that is my message box) has a current style display of "none.
Then you grab the offsetWidth of that element:

Expand|Select|Wrap|Line Numbers
  1. if(el.currentStyle["display"] == "none")
  2.             return 0;
  3.         var widthCSS = el.currentStyle["width"];
  4.         var bRegex = /thin|medium|thick/; // regex for css border width keywords
  5.         width = el.offsetWidth; // currently the width including padding + border
  6.  
In my code I simply set the display of the element to be "block"...because I discovered quickly that both the offsetWidth and the clientWidth will be 0 if the element's display value is none.

This is what I have right now:
Expand|Select|Wrap|Line Numbers
  1.  
  2. function ShowWindowAndInnerWindow(nameOfWindow,nameOfInnerWindow) 
  3.  
  4.  
  5.     var panel = document.getElementById(nameOfWindow);
  6.     //**Originally I had set the panel to be hidden while I dealt with moving the message box to the middle of the screen... see **comment continuation at the bottom.
  7.     //panel.style.visibility = 'hidden';
  8.  
  9.     //Here I set the panel to have a display of 'block' because if the panel has a display of 'none' you cannot get the clientWidth or offsetWidth values
  10.     panel.style.display = 'block';
  11.  
  12.     //I make sure that the panel is positioned absolute
  13.     panel.position = 'absolute';
  14.  
  15.    //This inner stuff, just ignore...
  16.     var innerPanel = document.getElementById(nameOfInnerWindow);
  17.     innerPanel.style.display = 'block';
  18.  
  19.     //here I grab the offsetWidth...but it doesn't work all the time....
  20.     var widthOfPanel = panel.offsetWidth;
  21.     //sooo here I hard code a width value
  22.     widthOfPanel=400;
  23.  
  24.     //The offsetHeight doesn't work all the time either, but it isn't so apparent when it doesn't work, so I don't care about setting a hard coded value.
  25.     var heightOfPanel = panel.offsetHeight;
  26.  
  27.     //determining how far from the left and the top that the browser should be drawn at in order to center it.
  28.     var left = Number(BrowserWidth())/2 - (widthOfPanel/2);    
  29.     var top = Number(BrowserHeight())/2 - (heightOfPanel/2);
  30.  
  31.     //Centering
  32.     if(document.documentElement)
  33.     {   
  34.         var topOffset = document.documentElement.scrollTop + top;
  35.         var leftOffset = document.documentElement.scrollLeft + left;
  36.         panel.style.top = topOffset + "px";
  37.         panel.style.left = leftOffset + "px";
  38.     }
  39.     else if(document.body)
  40.     { 
  41.         var topOffset = document.body.scrollTop + top;
  42.         var leftOffset = document.body.scrollLeft + left;    
  43.         panel.style.top = topOffset + "px";
  44.         panel.style.left = leftOffset + "px";
  45.     }
  46.     else
  47.     {
  48.  
  49.     }
  50.     //** comment continued from the above ** comment
  51.     //**Apparently when you set the panel to visibility of "hidden" then set it back to "visible", my buttons don't appear until I drag the message box 
  52.     //panel.style.visibility = 'visible';
  53.     return false;
  54. }
  55.  
Your code is much more complicated than mine, but you rely on the offsetWidth value as I do...this value is not working for me....it always returns 0 in the case that it is buried deep within other <divs>...............
Mar 28 '08 #8
If has a display value of none I return 0. I don't check the offsetWidth unless it has a display value of block or something != none

Expand|Select|Wrap|Line Numbers
  1.  
  2.         if(el.currentStyle["display"] == "none")
  3.             return 0;
  4.  
also clientWidth will return 0 in IE when the div's width is not set or is set to 'auto'

try this with the functions I wrote:

Expand|Select|Wrap|Line Numbers
  1.       function ShowWindowAndInnerWindow(nameOfWindow,nameOfInnerW  indow)
  2.       {
  3.  
  4.           var panel = document.getElementById(nameOfWindow);
  5.           //**Originally I had set the panel to be hidden while I dealt with moving the message box to the middle of the screen... see **comment continuation at the bottom.
  6.           //panel.style.visibility = 'hidden';
  7.  
  8.           //Here I set the panel to have a display of 'block' because if the panel has a display of 'none' you cannot get the clientWidth or offsetWidth values
  9.           panel.style.display = 'block';
  10.  
  11.           //I make sure that the panel is positioned absolute
  12.           panel.position = 'absolute';
  13.  
  14.          //This inner stuff, just ignore...
  15.           var innerPanel = document.getElementById(nameOfInnerWindow);
  16.           innerPanel.style.display = 'block';
  17.  
  18.           var widthOfPanel = getWidth(panel, true, true);
  19.           var heightOfPanel = getHeight(panel, true, true);
  20.  
  21.           //determining how far from the left and the top that the browser should be drawn at in order to center it.
  22.           var left = Number(BrowserWidth())/2 - (widthOfPanel/2);   
  23.           var top = Number(BrowserHeight())/2 - (heightOfPanel/2);
  24.  
  25.           //Centering
  26.           if(document.documentElement)
  27.           {   
  28.               var topOffset = document.documentElement.scrollTop + top;
  29.               var leftOffset = document.documentElement.scrollLeft + left;
  30.               panel.style.top = topOffset + "px";
  31.               panel.style.left = leftOffset + "px";
  32.           }
  33.           else if(document.body)
  34.           {
  35.               var topOffset = document.body.scrollTop + top;
  36.               var leftOffset = document.body.scrollLeft + left;   
  37.               panel.style.top = topOffset + "px";
  38.               panel.style.left = leftOffset + "px";
  39.           }
  40.           else
  41.           {
  42.  
  43.           }
  44.           //** comment continued from the above ** comment
  45.           //**Apparently when you set the panel to visibility of "hidden" then set it back to "visible", my buttons don't appear until I drag the message box
  46.           //panel.style.visibility = 'visible';
  47.           return false;
  48.       }
  49.  
Mar 28 '08 #9
Frinavale
9,735 Expert Mod 8TB
If has a display value of none I return 0. I don't check the offsetWidth unless it has a display value of block or something != none

Expand|Select|Wrap|Line Numbers
  1.  
  2.         if(el.currentStyle["display"] == "none")
  3.             return 0;
  4.  
also clientWidth will return 0 in IE when the div's width is not set or is set to 'auto'

try this with the functions I wrote:
...
I do not set the width or height values of my <div>s because are adjusted according to the content...in other words, they have a style="width:auto;height:auto;" by default in order to fit according to the content requirements.

Since I do not have a style set for my <div>...
Expand|Select|Wrap|Line Numbers
  1.    var height;
  2.     el = (typeof(el) == "string") ? document.getElementById(el) : el;
  3.  
  4.     if(window.getComputedStyle) { 
  5.         var style = document.defaultView.getComputedStyle(el, null);
  6.         if(style.getPropertyValue("display") == "none")
  7.             return 0;
  8.         height = parseInt(style.getPropertyValue("height"));
  9. //height will always be 0
  10.  
height will always be 0......
Mar 28 '08 #10
Frinavale
9,735 Expert Mod 8TB
I do not set the width or height values of my <div>s because are adjusted according to the content...in other words, they have a style="width:auto;height:auto;" by default in order to fit according to the content requirements.

Since I do not have a style set for my <div>...
Expand|Select|Wrap|Line Numbers
  1.    var height;
  2.     el = (typeof(el) == "string") ? document.getElementById(el) : el;
  3.  
  4.     if(window.getComputedStyle) { 
  5.         var style = document.defaultView.getComputedStyle(el, null);
  6.         if(style.getPropertyValue("display") == "none")
  7.             return 0;
  8.         height = parseInt(style.getPropertyValue("height"));
  9. //height will always be 0
  10.  
height will always be 0......
Actually, running it through FireBug, height is set to "auto"...
Mar 28 '08 #11
That's not what I'm getting. Are you in quirks mode?


I made a test file:
Expand|Select|Wrap|Line Numbers
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  2. <html>
  3. <head>
  4. <title>Get width/height - Test Page</title>
[code=javascript]
<script type="text/javascript">
//<![CDATA[

function getWidth(/* Object */ el, /* boolean */ includePadding, /* boolean */ includeBorder) {
var width;
el = (typeof(el) == "string") ? document.getElementById(el) : el;

if(window.getComputedStyle) { // FF, Safari, Opera
var style = document.defaultView.getComputedStyle(el, null);
if(style.getPropertyValue("display") == "none")
return 0;
width = parseInt(style.getPropertyValue("width"));

if(navigator.userAgent.toLowerCase().indexOf("oper a") != -1) {
// opera includes the padding and border when reporting the width/height - subtract that out
width -= parseInt(style.getPropertyValue("padding-left"));
width -= parseInt(style.getPropertyValue("padding-right"));
width -= parseInt(style.getPropertyValue("border-left-width"));
width -= parseInt(style.getPropertyValue("border-right-width"));
}

if(includePadding) {
width += parseInt(style.getPropertyValue("padding-left"));
width += parseInt(style.getPropertyValue("padding-right"));
}

if(includeBorder) {
width += parseInt(style.getPropertyValue("border-left-width"));
width += parseInt(style.getPropertyValue("border-right-width"));
}
} else { // IE
if(el.currentStyle["display"] == "none")
return 0;
var widthCSS = el.currentStyle["width"];
var bRegex = /thin|medium|thick/; // regex for css border width keywords
width = el.offsetWidth; // currently the width including padding + border

if(!includeBorder) {
var borderLeftCSS = el.currentStyle["borderLeftWidth"];
var borderRightCSS = el.currentStyle["borderRightWidth"];
var temp = document.createElement("DIV");
if(!bRegex.test(borderLeftCSS)) {
temp.style.width = borderLeftCSS;
el.parentNode.appendChild(temp);
width -= Math.round(temp.offsetWidth);
el.parentNode.removeChild(temp);
} else if(bRegex.test(borderLeftCSS)) {
if(el.offsetWidth > el.clientWidth && el.currentStyle["borderLeftStyle"] != "none") {
temp.style.width = "10px";
temp.style.border = borderLeftCSS + " " + el.currentStyle["borderLeftStyle"] + " #000000";
el.parentNode.appendChild(temp);
width -= Math.round((temp.offsetWidth-10)/2);
el.parentNode.removeChild(temp);
}
}
if(!bRegex.test(borderRightCSS)) {
temp.style.width = borderRightCSS;
el.parentNode.appendChild(temp);
width -= Math.round(temp.offsetWidth);
el.parentNode.removeChild(temp);
} else if(bRegex.test(borderRightCSS)) {
if(el.offsetWidth > el.clientWidth && el.currentStyle["borderRightStyle"] != "none") {
temp.style.width = "10px";
temp.style.border = borderRightCSS + " " + el.currentStyle["borderRightStyle"] + " #000000";
el.parentNode.appendChild(temp);
width -= Math.round((temp.offsetWidth-10)/2);
el.parentNode.removeChild(temp);
}
}
}

if(!includePadding) {
var paddingLeftCSS = el.currentStyle["paddingLeft"];
var paddingRightCSS = el.currentStyle["paddingRight"];
var temp = document.createElement("DIV");
temp.style.width = paddingLeftCSS;
el.parentNode.appendChild(temp);
width -= Math.round(temp.offsetWidth);
temp.style.width = paddingRightCSS;
width -= Math.round(temp.offsetWidth);
el.parentNode.removeChild(temp);
}
}

return width;
}

function getHeight(/* Object */ el, /* boolean */ includePadding, /* boolean */ includeBorder) {
var height;
el = (typeof(el) == "string") ? document.getElementById(el) : el;

if(window.getComputedStyle) { // FF, Safari, Opera
var style = document.defaultView.getComputedStyle(el, null);
if(style.getPropertyValue("display") == "none")
return 0;
height = parseInt(style.getPropertyValue("height"));

if(navigator.userAgent.toLowerCase().indexOf("oper a") != -1) {
// opera includes the padding and border when reporting the width/height - subtract that out
height -= parseInt(style.getPropertyValue("padding-top"));
height -= parseInt(style.getPropertyValue("padding-bottom"));
height -= parseInt(style.getPropertyValue("border-top-width"));
height -= parseInt(style.getPropertyValue("border-bottom-width"));
}

if(includePadding) {
height += parseInt(style.getPropertyValue("padding-top"));
height += parseInt(style.getPropertyValue("padding-bottom"));
}

if(includeBorder) {
height += parseInt(style.getPropertyValue("border-top-width"));
height += parseInt(style.getPropertyValue("border-bottom-width"));
}
} else { // IE
if(el.currentStyle["display"] == "none")
return 0;
var heightCSS = el.currentStyle["height"];
var bRegex = /thin|medium|thick/; // regex for css border width keywords
height = el.offsetHeight; // currently the height including padding + border

if(!includeBorder) {
var borderTopCSS = el.currentStyle["borderTopWidth"];
var borderBottomCSS = el.currentStyle["borderBottomWidth"];
var temp = document.createElement("DIV");
if(!bRegex.test(borderTopCSS)) {
temp.style.width = borderTopCSS;
el.parentNode.appendChild(temp);
height -= Math.round(temp.offsetWidth);
el.parentNode.removeChild(temp);
} else if(bRegex.test(borderTopCSS)) {
if(el.offsetHeight > el.clientHeight && el.currentStyle["borderTopStyle"] != "none") {
temp.style.width = "10px";
temp.style.border = borderTopCSS + " " + el.currentStyle["borderTopStyle"] + " #000000";
el.parentNode.appendChild(temp);
height -= Math.round((temp.offsetWidth-10)/2);
el.parentNode.removeChild(temp);
}
}
if(!bRegex.test(borderBottomCSS)) {
temp.style.width = borderBottomCSS;
el.parentNode.appendChild(temp);
height -= Math.round(temp.offsetWidth);
el.parentNode.removeChild(temp);
} else if(bRegex.test(borderBottomCSS)) {
if(el.offsetHeight > el.clientHeight && el.currentStyle["borderBottomStyle"] != "none") {
temp.style.width = "10px";
temp.style.border = borderBottomCSS + " " + el.currentStyle["borderBottomStyle"] + " #000000";
el.parentNode.appendChild(temp);
height -= Math.round((temp.offsetWidth-10)/2);
el.parentNode.removeChild(temp);
}
}
}

if(!includePadding) {
var paddingTopCSS = el.currentStyle["paddingTop"];
var paddingBottomCSS = el.currentStyle["paddingBottom"];
var temp = document.createElement("DIV");
temp.style.width = paddingTopCSS;
el.parentNode.appendChild(temp);
height -= Math.round(temp.offsetWidth);
temp.style.width = paddingBottomCSS;
height -= Math.round(temp.offsetWidth);
el.parentNode.removeChild(temp);
}
}

return height;
}


function ShowWindowAndInnerWindow(nameOfWindow,nameOfInnerW indow)
{

var panel = document.getElementById(nameOfWindow);

//**Originally I had set the panel to be hidden while I dealt with moving the message box to the middle of the screen... see **comment continuation at the bottom.

//panel.style.visibility = 'hidden';

//Here I set the panel to have a display of 'block' because if the panel has a display of 'none' you cannot get the clientWidth or offsetWidth values
panel.style.display = 'block';

//I make sure that the panel is positioned absolute

panel.position = 'absolute';

//This inner stuff, just ignore...
var innerPanel = document.getElementById(nameOfInnerWindow);
innerPanel.style.display = 'block';

var widthOfPanel = getWidth(panel, true, true);
var heightOfPanel = getHeight(panel, true, true);

// for testing
alert("getWidth(panel, true, true): " + getWidth(panel, true, true) + " \n getHeight(panel, true, true): " + getHeight(panel, true, true));

/*
//determining how far from the left and the top that the browser should be drawn at in order to center it.
var left = Number(BrowserWidth())/2 - (widthOfPanel/2);
var top = Number(BrowserHeight())/2 - (heightOfPanel/2);

//Centering
if(document.documentElement)
{
var topOffset = document.documentElement.scrollTop + top;
var leftOffset = document.documentElement.scrollLeft + left;
panel.style.top = topOffset + "px";
panel.style.left = leftOffset + "px";
}
else if(document.body)
{
var topOffset = document.body.scrollTop + top;
var leftOffset = document.body.scrollLeft + left;
panel.style.top = topOffset + "px";
panel.style.left = leftOffset + "px";
}
else
{

}
//** comment continued from the above ** comment
//**Apparently when you set the panel to visibility of "hidden" then set it back to "visible", my buttons don't appear until I drag the message box
//panel.style.visibility = 'visible';
return false;
*/
}

//]]>
</script>[/javascript]
Expand|Select|Wrap|Line Numbers
  1. </head>
  2. <body>
Expand|Select|Wrap|Line Numbers
  1. <script type="text/javascript">
  2. //<![CDATA[
  3.  
  4. var testMsgs = ["OK", "Yes", "No", "Cancel"];
  5.  
  6. function dynamicFunction() {
  7.  
  8.     for(i=0; i<testMsgs.length; i++) {
  9.         var outerDiv = document.createElement('DIV');
  10.         outerDiv.id = "outer";
  11.  
  12.         var innerDiv = document.createElement('DIV');
  13.         innerDiv.id = "inner";
  14.         innerDiv.innerHTML = testMsgs[i];
  15.  
  16.         outerDiv.appendChild(innerDiv);
  17.         document.body.appendChild(outerDiv);
  18.         ShowWindowAndInnerWindow("outer", "inner");
  19.         document.body.removeChild(outerDiv);
  20.     }
  21.  
  22. }
  23.  
  24. window.onload = dynamicFunction;
  25.  
  26. //]]>
  27. </script>
Expand|Select|Wrap|Line Numbers
  1. </body>
  2. </html>
Mar 28 '08 #12
Frinavale
9,735 Expert Mod 8TB
That's not what I'm getting. Are you in quirks mode?


I made a test file:
...
Thanks a lot for your help Mmurph.
Your solution will works fine.
I still have a problem determining the height the <div> in "particular" cases (when it is buried deep within other <div>s). I'm not sure why I'm having this problem because the <div> has a position of absolute.

I don't know what you mean by "quirks mode". I simply test my stuff in IE6, IE7 (which is the one that is causing the problem), Safari, Firefox, and Opera. I find Firefox's Firebug to be very helpful in debugging JavaScript so I tend to use it the most.

You have helped me in suggesting (via your code) that I should set the style's width and use that in order to get around the problem for the <div>s that are buried.

As a result, my message boxes are always positioned horizontally in the middle of the screen. This wasn't the case before. Thanks again for helping me with that solution.

I am still having problems positioning the box vertically (only when the <div> is buried deep within my .NET user controls on the page and online in IE7). I can live with it not properly centering vertically because most of these message boxes (buried deep) don't contain much data so it doesn't matter that they are a bit off. The ones that do contain a lot of data (so it's important to center them vertically) are not buried and work fine.

Thank you so much for your time and help Mmurph!

:)

-Frinny
Mar 29 '08 #13
drhowarddrfine
7,435 Expert 4TB
I'm not sure why I'm having this problem because the <div> has a position of absolute.
Didn't read all this but, just to add if it helps, absolutely positioned elements are removed from the normal flow and will collapse to zero if there are no contents or no height/width set.
I don't know what you mean by "quirks mode".
Quirks mode is what IE defaults to when a page has no doctype, has any junk before the doctype, or has an incorrect/incomplete doctype. It will follow the broken box model it set in 1996 and won't behave like any other browser. This will throw off margins/padding/width/height/and the color purple.
Mar 30 '08 #14

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

61 posts views Thread by Toby Austin | last post: by
4 posts views Thread by Tim Sheets | last post: by
4 posts views Thread by He Shiming | last post: by
3 posts views Thread by Les Juby | last post: by
2 posts views Thread by Dmitri Shvetsov | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.