2010-11-11 31 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