Also ist das die Antwort?
"Wenn Sie etwas berechnen müssen, es aber nicht anzeigen müssen , setzen Sie das Element auf visibility:hidden
und position:absolute
, fügen Sie es dem DOM-Baum hinzu, rufen Sie die offsetHeight ab und entfernen Sie es.
Ich habe das gleiche Problem bei einer Reihe von Elementen. Es gibt keine jQuery oder Prototype, die auf der Site verwendet werden können, aber ich bin alle dafür, die Technik auszuleihen, wenn sie funktioniert. Als Beispiel für einige Dinge, die nicht funktionierten, gefolgt von dem, was getan hat, habe ich den folgenden Code:
// Layout Height Get
function fnElementHeightMaxGet(DoScroll, DoBase, elementPassed, elementHeightDefault)
{
var DoOffset = true;
if (!elementPassed) { return 0; }
if (!elementPassed.style) { return 0; }
var thisHeight = 0;
var heightBase = parseInt(elementPassed.style.height);
var heightOffset = parseInt(elementPassed.offsetHeight);
var heightScroll = parseInt(elementPassed.scrollHeight);
var heightClient = parseInt(elementPassed.clientHeight);
var heightNode = 0;
var heightRects = 0;
//
if (DoBase) {
if (heightBase > thisHeight) { thisHeight = heightBase; }
}
if (DoOffset) {
if (heightOffset > thisHeight) { thisHeight = heightOffset; }
}
if (DoScroll) {
if (heightScroll > thisHeight) { thisHeight = heightScroll; }
}
//
if (thisHeight == 0) { thisHeight = heightClient; }
//
if (thisHeight == 0) {
// Dom Add:
// all else failed so use the protype approach...
var elBodyTempContainer = document.getElementById('BodyTempContainer');
elBodyTempContainer.appendChild(elementPassed);
heightNode = elBodyTempContainer.childNodes[0].offsetHeight;
elBodyTempContainer.removeChild(elementPassed);
if (heightNode > thisHeight) { thisHeight = heightNode; }
//
// Bounding Rect:
// Or this approach...
var clientRects = elementPassed.getClientRects();
heightRects = clientRects.height;
if (heightRects > thisHeight) { thisHeight = heightRects; }
}
//
// Default height not appropriate here
// if (thisHeight == 0) { thisHeight = elementHeightDefault; }
if (thisHeight > 3000) {
// ERROR
thisHeight = 3000;
}
return thisHeight;
}
Das versucht im Grunde alles und jedes, nur um ein Null-Ergebnis zu erhalten. ClientHeight ohne Auswirkungen. Mit den Problemelementen erhalte ich normalerweise NaN in der Basis und Null in den Versatz- und Bildlaufhöhen. Ich habe dann die Add DOM-Lösung und clientRects ausprobiert, um zu sehen, ob es hier funktioniert.
Am 29. Juni 2011 habe ich den Code tatsächlich aktualisiert, um zu versuchen, sowohl DOM als auch clientHeight mit besseren Ergebnissen als erwartet hinzuzufügen.
1) clientHeight war ebenfalls 0.
2) Dom hat mir tatsächlich eine Größe gegeben, die großartig war.
3) ClientRects gibt ein Ergebnis zurück, das fast identisch mit der DOM-Technik ist.
Da die hinzugefügten Elemente flüssiger Natur sind, werden sie beim Hinzufügen zu einem ansonsten leeren DOM Temp-Element entsprechend der Breite dieses Containers gerendert. Das wird komisch, weil das 30px kürzer ist, als es letztendlich endet.
Ich habe ein paar Schnappschüsse hinzugefügt, um zu veranschaulichen, wie die Höhe unterschiedlich berechnet wird.
Die Höhenunterschiede sind offensichtlich. Ich könnte sicherlich absolute Positionierung und versteckt hinzufügen, aber ich bin sicher, dass das keine Wirkung haben wird. Ich war weiterhin davon überzeugt, dass dies nicht funktionieren würde!
(Ich schweife weiter ab) Die Höhe ist niedriger als die tatsächlich gerenderte Höhe. Dies könnte durch Einstellen der Breite des DOM Temp-Elements auf das vorhandene übergeordnete Element behoben werden und könnte theoretisch ziemlich genau erfolgen. Ich weiß auch nicht, was sich daraus ergeben würde, sie zu entfernen und wieder an ihrem vorhandenen Standort hinzuzufügen. Da sie durch eine innerHTML-Technik angekommen sind, werde ich diesen anderen Ansatz verwenden.
* JEDOCH * Nichts davon war notwendig. Tatsächlich funktionierte es wie angegeben und gab die richtige Höhe zurück !!!
Als ich in der Lage war, die Menüs wieder sichtbar zu machen, hatte DOM erstaunlicherweise die richtige Höhe gemäß dem Fluid-Layout oben auf der Seite (279 Pixel) zurückgegeben. Der obige Code verwendet auch getClientRects, die 280px zurückgeben.
Dies wird im folgenden Schnappschuss veranschaulicht (aus Chrome entnommen, sobald es funktioniert hat).
Jetzt habe ich keine Ahnung, warum dieser Prototyp-Trick funktioniert, aber es scheint so. Alternativ funktioniert getClientRects auch.
Ich vermute, die Ursache für all diese Probleme mit diesen bestimmten Elementen war die Verwendung von innerHTML anstelle von appendChild, aber das ist an dieser Stelle reine Spekulation.