2010-11-11 33 views
2

當我使用overflow時,我遇到了似乎是webkit中的渲染問題:hidden;上一個孩子的div,然後增加使用javascript的父div的高度。我將問題簡化爲以下示例代碼。WebKit渲染使用overflow時出現問題:hidden;

從此源創建頁面,然後在WebKit瀏覽器(Safari,Chrome)中渲染。點擊「展開」按鈕,你會看到有溢出的div:hidden;設置,現在應該顯示基於擴展的父div高度不顯示。在Gecko(Firefox)和Trident(ID)瀏覽器中,這可以正常工作。

任何想法或建議的變通?基本上,我想手工構建一個包含父div中的文本的div表,並且我不希望文本包裝或擴展到div邊界之外。我需要能夠根據頁面上發生的其他事情來調整父div的高度。

謝謝! 巴特

<!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" xml:lang="en" lang="en"> 
<head> 
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" /> 
<meta http-equiv="Content-Language" content="en-us" /> 

<style type="text/css"> 

    #test_container { 
     width: 540px; 
    } 

    .column_allow_overflow { 
     float: left; 
     width: 100px; 
     height: 16px; 
     margin-left: 4px; 
     padding: 3px; 
    } 

    .column_no_overflow { 
     float: left; 
     width: 100px; 
     height: 16px; 
     margin-left: 4px; 
     padding: 3px; 
     overflow: hidden; 
    } 

    .background { 
     background-color: #444444; 
     color: #e5e5e5; 
    } 

    .data_row { 
     height: 22px; 
     width: 100%; 
     padding-bottom: 22px; 
     background-color: #cccccc; 
    } 

    #expand_container { 
     overflow:scroll; 
     overflow-x: hidden; 
     -ms-overflow-x: hidden; 
     height: 100px; 
     width: 100%; 
     background-color: #cccccc; 
    } 



</style> 

</head> 
<body> 

<div id="test_container"> 
<div class="data_row background"> 
    <button type="button" id="expand_button" onclick="expand();">Expand</button> 
</div> 
<div id="expand_container"> 
    <div class="data_row background"> 
     <div class="column_allow_overflow background"> 
      Overflow allowed 
     </div> 
     <div class="column_no_overflow background"> 
      Overflow NOT allowed 
     </div> 
     <div class="column_allow_overflow background"> 
      Overflow allowed 
     </div> 
     <div class="column_no_overflow background"> 
      Overflow NOT allowed 
     </div> 
    </div> 
    <div class="data_row background"> 
     <div class="column_allow_overflow background"> 
      Overflow allowed 
     </div> 
     <div class="column_no_overflow background"> 
      Overflow NOT allowed 
     </div> 
     <div class="column_allow_overflow background"> 
      Overflow allowed 
     </div> 
     <div class="column_no_overflow background"> 
      Overflow NOT allowed 
     </div> 
    </div> 
    <div class="data_row background"> 
     <div class="column_allow_overflow background"> 
      Overflow allowed 
     </div> 
     <div class="column_no_overflow background"> 
      Overflow NOT allowed 
     </div> 
     <div class="column_allow_overflow background"> 
      Overflow allowed 
     </div> 
     <div class="column_no_overflow background"> 
      Overflow NOT allowed 
     </div> 
    </div> 
    <div class="data_row background"> 
     <div class="column_allow_overflow background"> 
      Overflow allowed 
     </div> 
     <div class="column_no_overflow background"> 
      Overflow NOT allowed 
     </div> 
     <div class="column_allow_overflow background"> 
      Overflow allowed 
     </div> 
     <div class="column_no_overflow background"> 
      Overflow NOT allowed 
     </div> 
    </div> 
    <div class="data_row background"> 
     <div class="column_allow_overflow background"> 
      Overflow allowed 
     </div> 
     <div class="column_no_overflow background"> 
      Overflow NOT allowed 
     </div> 
     <div class="column_allow_overflow background"> 
      Overflow allowed 
     </div> 
     <div class="column_no_overflow background"> 
      Overflow NOT allowed 
     </div> 
    </div> 
</div> 
</div> 

<script> 

var expand = function (e) { 
    var button = document.getElementById('expand_button'); 
    var expand_container = document.getElementById('expand_container'); 

    button.onclick = contract; 

    expand_container.style.height = '160px'; 
    button.innerHTML = "Contract"; 
}; 

var contract = function (e) { 
    var button = document.getElementById('expand_button'); 
    var expand_container = document.getElementById('expand_container'); 

    button.onclick = expand; 

    expand_container.style.height = '100px'; 

    button.innerHTML = "Expand"; 
};     

</script> 

</body> 
</html> 
+0

而不是寫這麼多的代碼。在你的案例中使用jQuery的slideUp()和slideDown()或slideToggle() – zod 2010-11-11 20:19:17

+1

我實際上使用YUI3爲我的真實應用程序,但我想剝離這個香草的例子所有這一切。使用YUI時存在同樣的問題,所以我認爲它與我正在使用或未使用的JS庫有什麼關係。如果你能產生一個jquery的例子,那會很棒! – 2010-11-11 20:25:09

+0

「允許溢出」是什麼意思? – 2010-11-19 20:45:52

回答

1

編輯:現在我有一點時間來重新考慮這個問題,我意識到,我是在原來的答案說的東西是真實的,所有的,但是這是在迴流問題簡而言之,因爲它只會在你增加高度時出現。而且因爲它是一個迴流的問題,解決方法很簡單,添加位置:相對:

.data_row { 
    position: relative; 
    height: 22px; 
    width: 100%; 
    padding-bottom: 22px; 
    background-color: #cccccc; 
} 

驗證了該作品現在就好了。爲了教育目的,我將留下最初的答案。

我真的沒有一個很好的解決方案,但我認爲你的問題不僅僅是溢出:隱藏。這是float + overflow:hidden的組合。如果你刪除了浮動元素,並且,例如,在頁面上絕對放置了元素,那麼你的腳本在WebKit瀏覽器中工作正常。沒有溢出問題。我不確定這是不是你想要做的。問題是溢出實際上,不僅控制你的內容是否顯示如果容器太小,但與浮動相結合,它也可以設置容器本身的大小。

下面是它的一個很簡單的例子:

<div style="width: 500px; overflow: hidden;"> 
    <div style="width: 200px; float: left; height: 100%; background-color: red;"></div> 
    <div style="width: 200px; float: right; height: 100%; background-color: orange;"></div> 
    <div style="background-color: green; overflow: hidden;">aaa</div> 
<div> 

設置溢出,奇怪的是,正在爲float結算。它不清除元素上的浮點數,它會自行清除。這意味着應用了溢出的元素(自動或隱藏)將會擴展到需要包含浮動內部的子元素(而不是摺疊),假設高度未被聲明。

我想是因爲這個原因,您的設計存在問題。

我建議你使用display:table-cell,如果所有的項目都應該是相等的高度,表格佈局,如果你不是div純粹的,或絕對定位。

P.S.對不起,它可能應該是一個評論而不是答案,因爲我沒有真正提供一個好的解決方案,但評論太長了。

+0

伊利亞,你的建議添加位置:相對;給父母的div工作很好。由於這個問題,我一直在深入研究不同瀏覽器的迴流過程。我還沒有看到任何其他信息表明增加位置:相對;會有這種效果。我只是好奇,你怎麼知道這樣做? – 2010-11-22 16:29:21

+0

真相被告知,我從來沒有讀過它,這只是一種體驗。我曾在一些非常大的網站上工作,並且在IE6/7中常見的迴流問題很常見。因此,在嘗試了很多不同的事情之後,我意識到設置位置:在大多數情況下,相對於其中一個父元素,會強制瀏覽器完全重新計算子節點的迴流。這是最簡單的方法,其他方式包括JS代碼來修改導致迴流的屬性之一(例如,寬度,高度,顯示,位置,hasLayout等等) – 2010-11-22 18:09:45

0

我設法找到一個稍微醜陋的解決方法,修復它(注意:不妨跳到底部....我想出了一個更好的解決方案)。在expand_container元素中,我添加了另一個包含其他元素的div。在展開和合同函數中,我從它的父級(expand_container)中移除該元素,調整expand_container的大小,然後再將該div添加回來。這個問題不再發生。

<div id="expand_container" > 
    <div id="inner_container" style="margin:0; padding:0"> <!-- new element! --> 
    <div class="data_row background"> 
     <div class="column_allow_overflow background"> 
... 

然後...

var expand = function (e) { 
    var button = document.getElementById('expand_button'); 
    var expand_container = document.getElementById('expand_container'); 

    var inner_container = document.getElementById('inner_container'); // new 
    expand_container.removeChild(inner_container); // new 
    button.onclick = contract; 

    expand_container.style.height = '160px'; 

    expand_container.appendChild(inner_container); // new 
    button.innerHTML = "Contract"; 
}; 

等等

編輯:

僅供參考,如果你不想通過增加內部元件來改變你的DOM結構,相反,您可以抽出expand_container的所有子項,然後在調整大小後將它們全部添加回來。例如:

var len = expand_container.childNodes.length, i, a = []; 
for (i=len-1; i>=0; i--) 
a.push(expand_container.removeChild(
     expand_container.childNodes.item(i))); 

button.onclick = contract; 
expand_container.style.height = '160px'; 

for (i=len-1; i>=0; i--) 
expand_container.appendChild(a[i]); 

如果你有一百萬個元素,可能會變慢,但在你的例子中它就像一個魅力。

編輯2:好吧,只是想到了一些工作更好的東西....刪除expand_container並將其添加回相同的地方。再次,工作正常(即使nextSibling爲null):

var next = expand_container.nextSibling; 
var parent = expand_container.parentNode; 
parent.removeChild(expand_container); 

button.onclick = contract; 
expand_container.style.height = '160px'; 

parent.insertBefore (expand_container, next); 
+0

Rob,感謝您的建議。因爲它更乾淨,我將與伊利亞的解決方案一起進行。但是再次感謝您花時間處理這個問題! – 2010-11-22 16:32:28

+0

很酷,是的增加位置:相對肯定更簡單....無論如何是一個有趣的學習練習:) – rob 2010-11-22 16:48:33

0

我太接近崩潰了複製粘貼檢驗,在晚上的這個時候你的代碼(當然,這是晚上我在哪裏),但假設你的問題是,給定的包含元素的後代元素,當你更改相關樣式不正確的迴流,也嘗試加入:

expand_container.className = expand_container.className; 

後立即作風轉變。它看起來應該不會做任何事情,但是在我測試過的每個瀏覽器中,它都會導致瀏覽器重新排列容器及其所有內容,從而解決問題。

如果不是a known bug,您可能還想在http://bugs.webkit.org/上報告此錯誤。

+0

有趣....但我試過了,它不適用於這種情況。 – rob 2010-11-21 07:12:17

+0

這是我嘗試的第一件事,但它看起來不像這個詞的常識意義上的迴流問題。它看起來像是WebKit迴流代碼中的優化,所以可以像添加/刪除類或者執行display:none等操作輕微迴流。不起作用,它會強制迴流重新計算,但它出來的方式完全相同。位置:父親上的相對位置會導致使用不同的算法重新計算迴流。 – 2010-11-21 21:55:46