IE7相对/绝对定位错误,动态修改页面内容

时间:2010-03-18 20:34:02

标签: css internet-explorer-7 relative absolute

我想知道是否有人知道如何解决IE7中的以下问题:

<!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>
    <title>IE7 absolute positioning bug</title>
    <style type="text/css">
      #panel { position: relative; border: solid 1px black; } 
      #spacer { height: 100px; } 
      #footer { position: absolute; bottom: 0px; }
    </style>
    <script type="text/javascript"> 
      function toggle() { 
        var spacer = document.getElementById("spacer"); 
        var style = "block"; 
        if (spacer.style.display == "block" || spacer.style.display == "") { 
          style = "none"; 
        }
        spacer.style.display = style;
      }
    </script>
  </head>
  <body>
    <div id="panel">
      <button onclick="toggle();">Click me</button>
      <br /><br /><br />
      <div id="spacer"></div>
      <div id="footer">This is some footer</div>
    </div>
  </body>
</html>

当你在IE7中运行它时,你会看到修改“面板”的CSS后“footer”元素仍然存在。在IE8,FF和Chrome中测试的相同示例表现完全符合预期。

我已经尝试更新元素的类但是如果浏览器的窗口已经打开最大化并且没有对窗口进行进一步的大小更改(这是我们产品的大约90%的用例),这不起作用.... :() 我坚持使用基于CSS的解决方案但是我认为如果能够轻松地使IE7特定(这意味着其他浏览器将以标准方式运行),我可以在这种情况下例外。

请帮忙!

3 个答案:

答案 0 :(得分:68)

这与IE的“hasLayout bug”有关。相对定位的#panel父级没有布局,因此IE在重新调整大小/重新定位时会忘记重绘其子级。

如果您将overflow: hidden;添加到相对定位的#panel父级,问题就会出现。

#panel { position: relative; overflow: hidden; border: solid 1px black; } 

深入了解有关此IE错误的背景信息,请参阅优秀参考资料"On having layout",然后针对您的特定问题,特别是章节"Relatively positioned elements"

  

请注意,position: relative不会触发hasLayout,这会导致一些渲染错误,主要是消失或放错位置的内容。页面重新加载,窗口大小调整和滚动,选择可能会遇到不一致。使用此属性,IE会偏移元素但似乎忘记将“重绘”发送到其布局子元素(因为布局元素将在重绘事件的信号链中正确发送)。 / p>

overflow属性触发元素具有布局,另请参阅章节"Where Layout Comes From"

  

从IE7开始,overflow成为布局触发器。

答案 1 :(得分:2)

此解决方案不一定与动态内容有任何关系,但它对我有用(至少使页面变得易于管理):指定维度。 我只注意到IE7认为在IE工具中使用蹩脚的“通过点击选择元素”工具(ctrl + B)时div没有宽度。

答案 2 :(得分:0)

我创建了我的函数以触发重绘。也许这不是一个正确的解决方案,但它确实有效。

// Script to fix js positon bug on IE7

// Use that function, recomended delay: 700
function ie7fixElementDelayed(elements, delay) {
    window.setTimeout(
        function () {
            if(navigator.appVersion.indexOf("MSIE 7.") != -1) {
                ie7fixElement(elements);
            }
        },
        delay
    );
}

function ie7fixElement(elements) {
    elements.each(function(i) {
        var element = $(this);
        var orginalDisplayValue = element.css("display");

        element.css("display", "none");
        element.css("display", orginalDisplayValue);
    });
}

样本用法:

ie7fixElementDelayed($('#HandPickedWidget .widget'), 700);