30

我想知道是否有人知道如何在 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 后“页脚”元素仍然存在。在 IE8、FF 和 Chrome 中测试的相同示例的行为完全符合预期。

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

请帮忙!

4

3 回答 3

68

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

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

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

关于这个 IE 错误的深入背景信息可以在优秀的参考“关于布局”中找到,然后针对您的特定问题,特别是“相对定位的元素”一章:

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

overflow属性触发元素具有布局,另请参阅“布局来自何处”一章:

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

于 2010-03-18T20:45:58.647 回答
2

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

于 2011-08-11T16:44:59.530 回答
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);
于 2013-07-16T14:03:26.937 回答