it-swarm.com.de

IE7 relativer/absoluter Positionierungsfehler mit dynamisch geändertem Seiteninhalt

Ich habe mich gefragt, ob es jemanden gibt, der eine Idee hat, wie er mit dem folgenden Problem in IE7 umgehen soll:

<!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>

Wenn Sie dies in IE7 ausführen, sehen Sie, dass das "footer" -Element nach dem Ändern des CSS für "panel" erhalten bleibt. Das gleiche Beispiel, das in IE8, FF und Chrome getestet wurde, verhält sich genau wie erwartet.

Ich habe bereits versucht, die Elementklasse zu aktualisieren. Dies funktioniert jedoch nicht, wenn das Browserfenster maximiert geöffnet wurde und keine weiteren Größenänderungen am Fenster vorgenommen wurden (dies entspricht etwa 90% der Anwendungsfälle, die wir für unser Produkt haben ... . :() Ich bin mit einer CSS-basierten Lösung beschäftigt, aber ich denke, dass ich in diesem Fall eine Ausnahme machen kann, wenn dies leicht IE7-spezifisch gemacht werden kann (was bedeutet, dass sich andere Browser standardmäßig verhalten mit diesem).

Bitte helfen 

30

Dies hängt mit dem "hasLayout-Fehler" des IE zusammen. Das relativ positionierte #panel-übergeordnete Element verfügt nicht über ein Layout. Daher vergisst IE das Neuzeichnen seiner untergeordneten Elemente, wenn dessen Größe geändert/neu positioniert wird. 

Das Problem wird behoben, wenn Sie overflow: hidden; zu dem relativ positionierten #panel-übergeordneten Element hinzufügen.

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

Ausführliche Hintergrundinformationen zu diesem IE - Fehler finden Sie in der ausgezeichneten Referenz "Über Layout" und dann für Ihr spezielles Problem speziell im Kapitel "Relativ positionierte Elemente" :

Beachten Sie, dass position: relative kein hasLayout auslöst, was zu einigen Darstellungsfehlern führt, die hauptsächlich verschwinden oder falsch platzieren. Inkonsistenzen können auftreten, wenn die Seite neu geladen, die Fenstergröße geändert und gescrollt wird. Mit dieser Eigenschaft versetzt IE das Element , scheint jedoch zu vergessen, ein "Neuzeichnen" an seine untergeordneten Layoutelemente zu senden (da ein Layoutelement in der Signalkette der Neuzeichnungsereignisse korrekt gesendet hätte).

Die overflow-Eigenschaft bewirkt, dass das Element ein Layout hat, siehe auch das Kapitel "Woher das Layout kommt" :

Ab IE7 wurde overflow zum Layout-Auslöser.

68
BalusC

Diese Lösung hat nicht unbedingt etwas mit dynamischem Inhalt zu tun, aber sie hat für mich funktioniert (zumindest hat die Seite zu einem verwaltbaren Grad verzerrt): Dimensionen angeben . Ich habe nur bemerkt, dass IE7 der Meinung war, dass ein div keine Breite hat, wenn das bescheidene Werkzeug "Element durch Klicken auswählen" (Strg + B) in den Werkzeugen IE verwendet wird. 

2

Ich habe meine Funktion erstellt, um das Neuzeichnen auszulösen Vielleicht ist es keine richtige Lösung, aber es funktioniert.

// 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);
    });
}

Verwendungsbeispiel:

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