これが答えですか?
「何かを計算する必要があるが表示しない場合は、要素をに設定しvisibility:hidden
、position:absolute
それをDOMツリーに追加し、offsetHeightを取得して削除します(これは、プロトタイプライブラリが最後にチェックした行の背後にあるものです)。」
多くの要素で同じ問題があります。サイトで使用するjQueryまたはPrototypeはありませんが、機能する場合は、この手法を借用することに賛成です。機能しなかったいくつかの例として、何が続いたのか、次のコードを示します。
// 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;
}
これは基本的に何もせず、すべてゼロの結果を得るためだけに試みます。影響のないClientHeight。問題のある要素を使用すると、通常はベースでNaNが取得され、オフセットとスクロールの高さがゼロになります。次に、Add DOMソリューションとclientRectsを試して、ここで機能するかどうかを確認しました。
2011年6月29日、実際にコードを更新して、DOMとclientHeightの両方に追加して、予想よりも良い結果が得られるようにしました。
1)clientHeightも0でした。
2)ドムは実際に私に素晴らしい高さを与えました。
3)ClientRectsは、DOM手法とほぼ同じ結果を返します。
追加された要素は本質的に流動的であるため、他の場合は空のDOM Temp要素に追加されると、それらはそのコンテナの幅に従ってレンダリングされます。最終的には30px短くなるので、これは奇妙になります。
高さの計算方法が異なる例を示すために、いくつかのスナップショットを追加しました。
高さの違いは明らかです。私は確かに絶対配置を追加して非表示にすることができますが、それは効果がないと確信しています。私はこれがうまくいかないと確信し続けました!
(さらに説明します)高さが実際のレンダリングされた高さよりも低くなります(レンダリング)。これは、DOM Temp要素の幅を既存の親と一致するように設定することで対処でき、理論的にはかなり正確に実行できます。また、それらを削除して既存の場所に戻すとどうなるかわかりません。彼らがinnerHTMLテクニックを介して到着したとき、私はこの異なるアプローチを使用して探します。
*しかし*それは必要ありませんでした。実際、それは宣伝どおりに機能し、正しい高さを返しました!!!
メニューを再び表示できるようになったとき、驚くべきことに、DOMはページ上部の流動レイアウトごとに正しい高さ(279px)を返しました。上記のコードは、280pxを返すgetClientRectsも使用しています。
これは次のスナップショットに示されています(Chromeから動作した後に取得)。
今、私はそのプロトタイプのトリックが機能する理由を考えていませんが、そうです。または、getClientRectsも機能します。
これらの特定の要素に関するこのすべての問題の原因は、appendChildの代わりにinnerHTMLを使用したためだと思いますが、これは現時点では純粋な推測です。