Javascript 元素 offsetHeight 始终为“0”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6937378/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 23:50:55  来源:igfitidea点击:

Element offsetHeight always "0"

javascripthtmlcss

提问by kumarjcet

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

为什么我得到 Element offsetHeight "0"?甚至元素原始高度未显示

<!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>

回答by Lonnie Best

Sometimes offsetHeight will return zero because the element you've created has not been rendered in the Dom yet. I wrote this function for such circumstances:

有时 offsetHeight 会返回零,因为您创建的元素尚未在 Dom 中呈现。我为这种情况编写了这个函数:

function getHeight(element)
{
    element.style.visibility = "hidden";
    document.body.appendChild(element);
    var height = element.offsetHeight + 0;
    document.body.removeChild(element);
    element.style.visibility = "visible";
    return height;
}

回答by Kamyar Infinity

You are trying to get offsetHeightof a hidden element. the css .navbar ul li ulhas display:nonethat would make all of it's content invisible, including crossobjand you can't get height of elements that are not displayed, their height is simply put 0.

您正在尝试获取offsetHeight隐藏元素。的CSS.navbar ul li uldisplay:none这将使它的所有内容不可见的,包括crossobj你不能让不显示的元素的高度,其高度简单地说0

回答by Shaun R Stewart

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 noneand 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.

另一个“技巧”是暂时将对象可见性设置为hidden,将其显示设置为阻止。然后得到offsetHeight. 然后只需通过将 display 设置为none并将可见性设置为 来反转它visible。当然,这只有在不会破坏页面布局的流程时才有效(即页面中的所有内容都在移动,好像有什么东西在那里,但空间中没有显示任何内容)。但是,如果它是 z 索引或浮动或绝对定位的东西,它应该可以正常工作。

回答by HazeyAce

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.

应用于 DOM 元素的更改不会立即应用,在单个执行周期中对 DOM 所做的所有更改都会被收集并在一次重绘中应用。

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 是在每次重绘之前执行的方法。

requestAnimationFrame(() => {
    /* should be able to get offsetHeight here */
};

回答by Tayyab Mughal

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

有一种更简单的方法可以做到这一点。我有许多具有不同 ID 和名称的 iframe,所以这就是我所做的。我在父窗口中添加了按钮,单击时执行此操作

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

})

})