2009-09-24 44 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