Element offsetHeight always "0"

Viewed 36734

Why I am getting Element offsetHeight "0"? even element original height is not showing

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style>
/* Added for Menu    */
.navbar
{
  list-style: none;`enter code here`
  padding: 0 10px;
  margin: 0;
  float: left;
  width: 980px;
  background: url(images/navbar.gif) repeat-x;
}
.navbar ul
{
 list-style: none;
  padding: 0px;
  margin: 0;
  float: left;
  width: 260px;
}
.navbar ul li
{
    float:left;
    position:relative;
    z-index:1000;
    margin:0px;
    padding:0px;
}
.navbar ul li ul
{
    display:none;
    border:none;
    width: 260px;
    padding:0 0px 0px 0px;
}
.navbar ul li a
{
     font-size: 12px;
     float:left;
     display:block;
     line-height:3.1em;
     padding:0 16px 0 16px;
     text-decoration:none;
     color:#FFF;
}
.navbar ul li:hover
{
    width:auto;
}
.navbar ul li:hover a
{
    background:url(images/navbar_subnav.png)  repeat-x scroll 0 0 transparent;          text-decoration:none;
}
.navbar ul li:hover ul
{
    display:block;
    position:absolute;
    z-index:998;
    top:0px;
    margin-top:25px;
    left:0;
}
.navbar ul li:hover ul li ul
{
    background-position: center bottombottom;
    cursor: pointer;
}
.navbar ul li:hover ul li a
{
    display:block;
    line-height:1.3em;
    padding:4px 16px 4px 16px;
    border-bottom:1px solid #205284;
    border-left:1px solid #205284;
    border-right:1px solid #205284;
    border-top:1px solid #205284;
    z-index: 10000;
    width:200px;
  }
.navbar ul li:hover ul li a:hover
{
     background-color:#000;
     text-decoration:underline;
     color: #0099FF;
     cursor: hand;

}
.navbar ul li a:hover ul
{
    display:block;
    position:absolute;
    z-index: 998;
    top:3.1em;
    t\op:3.0em;
    left:0;
    marg\in-top:0.1em;
}
.navbar ul li a:hover ul li a
 {
    display:block;
    height:1px;
    line-height:1.3em;
    padding:4px 16px 4px 16px;
    background-color:#000;
    font-weight:normal;
    color:#FFF;
}
.navbar ul li a:hover ul li a ul
{
    visibility:hidden;
    height:0px;
    width:0px;
    position:absolute;
    z-index: 997;
}
.navbar ul li a:hover ul li a:hover
{
    background-color:#000;
    text-decoration:underline;
}

</style>
</head>

<body>
<div class="navbar">
<ul>
            <li>
                <a href="#">menu item 1</a>
                <ul style="top:0px" >
                    <li style="width:288px;"><center><a href="#" onmouseover="movedown()" onmouseout="stopscroll()"><img src="images/menu-arrow-down.png" width="8" height="6"   alt="Down"></a></center></li>
<script> //<![CDATA[
var speed=2
iens6=document.all||document.getElementById
ns4=document.layers
if (iens6){
document.write('<div id="container" style="position:relative;width:310px;height:165px;overflow:hidden;border:0px solid #205284">')
document.write('<div id="content" style="position:absolute;width:290px;left:0px;top:-1px;">')
}
//]]></script>
<ilayer name="nscontainer" width="190">
<layer name="nscontent" width="290" height="155" visibility="hidden">
                    <li style="top:-1px;"><a href="#">sub menu item 1  menu item 1</a></li>
                    <li style="top:-1px;"><a href="#">sub menu item 2  menu item 1</a></li>                    <li style="top:-1px;"><a href="#">sub menu item 3</a></li>
                    <li style="top:-1px;"><a href="#">sub menu item 1</a></li>
                    <li style="top:-1px;"><a href="#">sub menu item 1</a></li>
                    <li style="top:-1px;"><a href="#">sub menu item 2</a></li>              
                    <li style="top:-1px;"><a href="#">sub menu item 3</a></li>
                    <li style="top:-1px;"><a href="#">sub menu item 1</a></li>
                    <li style="top:-1px;"><a href="#">sub menu </a></li>
                    <li style="top:-1px;"><a href="#">sub menu </a></li>
                    <li style="top:-1px;"><a href="#">sub menu </a></li>
                    <li style="top:-1px;"><a href="#">sub menu </a></li>              
                    <li style="top:-1px;"><a href="#">sub menu </a></li>
                    <li style="top:-1px;"><a href="#">sub menu</a></li>

</layer>
</ilayer>
<script> //<![CDATA[
if (iens6)
{
document.write('</div></div>')
var crossobj=document.getElementById? document.getElementById('content') : document.all.content
//alert("document.getElementById('content').offsetHeight :"+ document.getElementById('content').offsetHeight);
alert("crossobj.prototype.outerHeight" + crossobj.prototype.outerHeight);
var contentheight=crossobj.offsetHeight
//var contentheight=document.getElementById('content').style.height;
//alert("ContentHeight :"+contentheight);
}
else if (ns4)
{
    var crossobj=document.nscontainer.document.nscontent
    var contentheight=crossobj.clip.height
}
function movedown(){
if (window.moveupvar) clearTimeout(moveupvar)
{
    if (iens6&&parseInt(crossobj.style.top)>=(contentheight*(-1)+100))
    {
        crossobj.style.top=parseInt(crossobj.style.top)-speed+"px"
    }
    else if(ns4&&crossobj.top>=(contentheight*(-1)+100))
    {
        crossobj.top-=speed
    }
    /*else
    {
        crossobj.style.top=parseInt(crossobj.style.top)-speed+"px"
    }*/
}
    movedownvar=setTimeout("movedown()",20)
}
function moveup()
{
    if (window.movedownvar) clearTimeout(movedownvar)
    {
        if (iens6&&parseInt(crossobj.style.top)<=0)
        {
        crossobj.style.top=parseInt(crossobj.style.top)+speed+"px"
        }
        else if (ns4&&crossobj.top<=0)
        {
        crossobj.top+=speed
        }
        moveupvar=setTimeout("moveup()",20)
    }
}
function getcontent_height()
{
    if (iens6)
    {
        //alert("getcontent_height : "+document.getElementById("content").style.height);
        //contentheight=document.getElementById("content").style.height;
        contentheight=crossobj.offsetHeight
    }
    else if (ns4)
    {
        document.nscontainer.document.nscontent.visibility="show"
    }
}
window.onload=getcontent_height;
//]]></script>
                    <li><center><a href="#" onmouseover="moveup()" onmouseout="stopscroll()"><img src="images/menu-arrow-down.png" width="8" height="6" alt="Down"></a> </center></li>
                </ul>
            </li>
           </ul> 
      </div>    
</body>
</html>
5 Answers

UPDATE

Changes applied to the DOM elements are not applied immediately, all the changes made to the DOM in a single execution cycle are collected and applied in one repaint.

So you need to wait for the repaint to complete before trying to read the updated dimensions of the element.

requestAnimationFrame is a method that is executed before every repaint.

requestAnimationFrame(() => {
  element = document.getElementById("your_ID");
  let height = element.offsetHeight;
  console.log("debug height: " + height);
});

Another "trick" is to momentarily set the objects visibility to hidden, its display to block. And then get the offsetHeight. Then just reverse that by setting display to none and visibility to visible. Of course this will only work if it will not disrupt the flow of the page layout (i.e. everything shifts in the page as if something is there, but nothing is displayed in the space). But if it is something that is z-indexed or floating or perhaps absolute positioned it should work fine.

There is a more easiest way to do that. I had many iframes with different IDs and names so here is what I did. I added the button in the parent window, which on click does this

var iWin = document.querySelector(your iframe id here).contentWindow;
iWin.postMessage("button is clicked","*");
//you can send the id of the required frame as the message

Put this inside the child window script.

window.onload = function(){
          window.addEventListener('message',(e)=>{
            if(e.data == "showcomment"){
              //I am just sending the height and iframe name cause I have many iframes 
              //with different names  
              window.parent.postMessage({winHeight:document.body.offsetHeight,winName: 
              window.name},"*");
            }
          });
    }

Now last step put this in the parent window script

window.addEventListener('message',(e)=>{
//here I am getting element with that name and setting its height you can change it
document.getElementsByName(`${e.data.winName}`)[0].height = e.data.winHeight + 10;
//I added 10 as extra height , you can ignore it

})

Related