2009-09-24 53 views
19

我需要测量隐藏元素内的div的offsetHeight。需要找到页面上隐藏div的高度(设置为显示:无)

<div id="parent" style="display: none;"> 
    <div id="child">Lorem Ipsum dolor sit amet.</div> 
</div> 

父DIV 必须设置为 “display:none”。我无法控制这一点。我意识到,子div的offsetHeight将为0.我需要找到一种解决方法。

我玩过的东西是当页面加载时,我复制父节点的子节点,注入设置为“visiblity:hidden”的页面上的div。然后我测量这些元素的高度,并在完成时移除节点。

还有其他想法吗?

更新: 我结束了不得不做的是:

使用YUI 2,在页面加载时,我发现,要么设置为显示给定类名的所有元素:其无,或高度和宽度为0(这是测量某个元素是否存在的一种方法,或者父级设置为显示:无)。然后我设置该元素来显示:block。然后我检查了它的父母是否有相同的事情,并向父母展示,直到找到可见的父母。一旦最高显示:无祖先设置为显示:块,我可以测量我的元素。

一旦所有元素都被测量,我将所有元素都重置为显示:无。

回答

18

您需要使元素的父可见为那一个非常短的时刻,而你得到元素的尺寸。在一个通用的解决方案中,所有的祖先通常都会遍历并可见。然后他们的display值被设置回原来的值。

当然有性能问题。

我们考虑的Prototype.js实施这一做法,但结束了getWidthgetHeight做才可见实际元素,而无需遍历祖先。

替代解决方案的问题 - 例如将元素从“隐藏的”父元素中取出 - 是某些元素一旦超出其“常规”层次结构可能不再适用于元素。如果你有这样的结构:

<div class="foo" style="display:none;"> 
    <div class="bar">...</div> 
</div> 

这些规则:

.bar { width: 10em; } 
.foo .bar { width: 15em; } 

然后获取元件出其父实际上会导致错误的尺寸。

+1

我考虑过这个......这似乎可能是非常资源密集型的......你怎么看? – 2009-09-24 19:13:02

+0

编辑帖子回答您的关注(以及关于替代方法的一些想法)。 – kangax 2009-09-24 21:28:43

+1

我无法看到任何闪烁,同时每分钟显示元素。我采取了只在显示高度时才显示它的方法,然后隐藏它。这也是jQuery的slideToggle()所做的。它很好地工作。 +1 – 2013-01-08 22:13:53

13

您可以克隆该元素,将其绝对定位在-10000,-10000处,测量克隆并销毁它。

+0

如果我克隆它,我必须注入它,对吧? – 2009-09-24 19:12:07

+0

是的,你将不得不 - 在理想情况下只是在原来的,所以任何CSS仍然完好无损。 – James 2009-09-24 21:06:45

+0

绝妙的想法。把它变成一个jQuery函数:http://stackoverflow.com/a/12463110/373345 – dsomnus 2012-09-17 16:14:08

0

使用z-index隐藏非透明元素下的元素,显示它并获取高度。

1

直到元素呈现,它没有高度。即使克隆父对象并将其显示在用户看不到的地方,也不能保证克隆将具有与隐藏对象的最终大小相同的高度。

有很多事情可能会影响不需要在克隆中呈现的高度--DOM中的任何内容及其与CSS规则的交互可能会导致渲染DOM中其他任何元素的更改。克隆整个文档(即使这不是傻瓜证明),您无法确定隐藏对象的高度。

如果必须知道高度前,它显示给用户,你必须通过显示它尽可能短的时间尽可能然后再次隐藏它“砍”它。最有可能的是,用户会看到这种呃逆,并且不会因结果而感到高兴。

+0

可以通过使用负面定位和使用可见性将其从页面中移出来避免“打嗝”:可能隐藏 – 2009-09-24 19:31:21

+2

但是,如果您将其移出页面上的真实位置,则无法保证高度是正确的。你可以100%确定它是正确的唯一方法是在原地显示它。将它移到其他地方可能会给你正确的答案,但是你必须接受渲染差异的可能性。 – 2009-09-24 19:44:29

+0

这就是为什么元素不应该移动;相当 - 隐藏着“知名度:隐藏”。 – kangax 2009-09-25 02:12:55

1

因此,您甚至不能将display:none;更改为height:0; overflow:hidden;?也许你可以重写你自己的样式表,像这样:

div#parent { display: block !important; height:0; overflow:hidden; } 

接着,当你使用YUI(假设YUI 2),你可以这样做:

var region = YAHOO.util.Dom.getRegion('child'); 

要获得的尺寸和偏移孩子。

0

我卷绕不必做什么是这样的:

使用锐2,在页面加载,我发现,要么设置为显示该给定的类名的所有元素:其高度和宽度为0无,或(这是衡量一个元素是否存在的一种方法,或者父母被设置为显示:无)。然后我设置该元素来显示:block。然后我检查了它的父母是否有相同的事情,并向父母展示,直到找到可见的父母。一旦最高显示:无祖先设置为显示:块,我可以测量我的元素。

一旦所有元素都被测量,我将所有元素都重置为显示:无。

-5

你试过这个吗?

setTimeout('alert($(".Var").height());',200); 
1

尝试使用:

#parent{ display:block !important; visibility:hidden; position:absolute} 
8

如果使用style.display = "none",该元素将有0的宽度和高度,
但使用style.visibility = "hidden"相反,该元素将有宽度和高度的计算方法浏览器(通常情况下)。

+0

我认为这将是最好的解决方案。如果隐藏的元素阻碍,你甚至可以设置一个z-index。 – 2016-11-03 15:29:04

4

因此,这里的基础上lod3n的答案,并与999的评论的帮助下工作的jQuery解决方案:

 
var getHiddenElementHeight = function(element){ 
    var tempId = 'tmp-'+Math.floor(Math.random()*99999);//generating unique id just in case 
    $(element).clone() 
    .css('position','absolute') 
    .css('height','auto').css('width','1000px') 
    //inject right into parent element so all the css applies (yes, i know, except the :first-child and other pseudo stuff.. 
    .appendTo($(element).parent()) 
    .css('left','-10000em') 
    .addClass(tempId).show() 
    h = $('.'+tempId).height() 
    $('.'+tempId).remove() 
    return h; 
} 

享受!

+2

如果你的父母被隐藏了,该怎么办? – Rantiev 2015-04-08 17:09:59

+0

@Rantiev很好的捕获,当父母被隐藏,它仍然返回0 .... – 2016-12-14 14:24:28

6

由纯JS的解决方案,没有jQuery和没有克隆(我的猜测是更快)

var getHeight = function(el) { 
    var el_style  = window.getComputedStyle(el), 
     el_display = el_style.display, 
     el_position = el_style.position, 
     el_visibility = el_style.visibility, 
     el_max_height = el_style.maxHeight.replace('px', '').replace('%', ''), 

     wanted_height = 0; 

    // if its not hidden we just return normal height 
    if(el_display !== 'none' && el_max_height !== '0') { 
     return el.offsetHeight; 
    } 

    // the element is hidden so: 
    // making the el block so we can meassure its height but still be hidden 
    el.style.position = 'absolute'; 
    el.style.visibility = 'hidden'; 
    el.style.display = 'block'; 

    wanted_height  = el.offsetHeight; 

    // reverting to the original values 
    el.style.display = el_display; 
    el.style.position = el_position; 
    el.style.visibility = el_visibility; 

    return wanted_height; 
} 

这里是演示 https://jsfiddle.net/xuumzf9k/1/

请让我知道如果你能找到任何改善到这个(因为我在我的主要项目中使用这个)

+3

你最好想想,它的祖先https://jsfiddle.net/rantiev/xuumzf9k/2/ – Rantiev 2015-04-08 17:12:47

+0

很酷的把戏,谢谢! – 2016-07-16 06:23:17

+0

绝对定位似乎没有必要,并且会影响高度,至少在Chrome中使用默认浏览器样式的段落时。 – curtisblackwell 2017-02-15 17:42:40