2011-11-18 10 views
9

私は開いていると閉じたスライドのテーブルを持つWebページを作成しています。最初は、いくつかの行が閉じられていて(display: none)、それらをスライドさせて開きます。高さの設定とoverflow: hiddenの使用はテーブルの行には作用しないので、テーブル内のdivの高さを変更しています。表示されていない要素の高さを確認する方法

これは機能します。唯一の問題は、スライドを開く前にdivの高さを知る必要があることです。これは不可能なようです。私が考えることができる1つの解決策は、行が表示されたページをロードし、それらを反復し、高さを格納し、それらを隠すことです。私はこのソリューションが気に入らないのは、ページが読み込まれるときに飛び回るからです。

私の問題は単純で実行可能な例です。

<!DOCTYPE HTML> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<style type="text/css"> 
table, td {border: 1px solid black;} 
#lower_row {display: none;} 
#lower_div {overflow: hidden;} 
</style> 
<script type="text/javascript"> 
function toggleLower() { 
    lowerRow = document.getElementById("lower_row"); 
    lowerDiv = document.getElementById("lower_div"); 
    if (getStyle(lowerRow, "display") == "none") { 
     lowerRow.style.display = "table-row"; 
    } 
    else { 
     lowerRow.style.display = "none"; 
    } 
    showHeight(); 
} 
function showHeight() { 
    lowerDiv = document.getElementById("lower_div"); 
    document.getElementById("info").innerHTML = getStyle(lowerDiv, "height"); 
} 
// Return a style atribute of an element. 
// J/S Pro Techniques p136 
function getStyle(elem, name) { 
    if (elem.style[name]) { 
     return elem.style[name]; 
    } 
    else if (elem.currentStyle) { 
     return elem.currentStyle[name]; 
    } 
    else if (document.defaultView && document.defaultView.getComputedStyle) { 
     name = name.replace(/([A-Z])/g, "-$1"); 
     name = name.toLowerCase(); 
     s = document.defaultView.getComputedStyle(elem, ""); 
     return s && s.getPropertyValue(name); 
    } 
    else { 
     return null; 
    } 
} 
</script> 
</head> 

<body onload="showHeight()"> 
<p>The height the lower row is currently <span id="info"></span></p> 
<table> 
<tr id="upper_row" onclick="toggleLower()"><td><p>Click me to toggle the next row.</p></td></tr> 
<tr id="lower_row"><td><div id="lower_div"><p>Peekaboo!</p></div></td></tr> 
</table> 

</body> 
</html> 

編集1:

一つの提案された解決策は、ページ外のdivを移動することです。私はそれを働かせることができません、そして、私はそれが高さがテーブルの幅に依存するので、それが間違った高さを持つと思います。

私はvisibility:hiddenを使用するという解決策に取り組んでいますが、問題があります。依然として少量のスペースしか占めず、報告された高さは間違っています。ここではその解決策の例です:

<!DOCTYPE HTML> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<style type="text/css"> 
table {width: 250px;} 
table, td {border: 1px solid black;} 
#lower_row {position: absolute; visibility: hidden} 
#lower_div {overflow: hidden;} 
</style> 
<script type="text/javascript"> 
function toggleLower() { 
    lowerRow = document.getElementById("lower_row"); 
    lowerDiv = document.getElementById("lower_div"); 
    if (getStyle(lowerRow, "visibility") == "hidden") { 
     lowerRow.style.visibility = "visible"; 
     lowerRow.style.position = "static"; 
    } 
    else { 
     lowerRow.style.visibility = "hidden"; 
     lowerRow.style.position = "absolute"; 
    } 
    showHeight(); 
} 
function showHeight() { 
    lowerDiv = document.getElementById("lower_div"); 
    document.getElementById("info").innerHTML = getStyle(lowerDiv, "height"); 
} 
// Return a style atribute of an element. 
// J/S Pro Techniques p136 
function getStyle(elem, name) { 
    if (elem.style[name]) { 
     return elem.style[name]; 
    } 
    else if (elem.currentStyle) { 
     return elem.currentStyle[name]; 
    } 
    else if (document.defaultView && document.defaultView.getComputedStyle) { 
     name = name.replace(/([A-Z])/g, "-$1"); 
     name = name.toLowerCase(); 
     s = document.defaultView.getComputedStyle(elem, ""); 
     return s && s.getPropertyValue(name); 
    } 
    else { 
     return null; 
    } 
} 
</script> 
</head> 

<body onload="showHeight()"> 
<p>The height the lower row is currently <span id="info"></span></p> 
<table> 
<tr id="upper_row" onclick="toggleLower()"><td><p>Click me to toggle the next row.</p></td></tr> 
<tr id="lower_row"><td><div id="lower_div"><p>This is some long text. This is some long text. This is some long text. This is some long text.</p></div></td></tr> 
</table> 

</body> 
</html> 

編集2:ソリューション

ポールの答えは私の質問を解決する:表示されていない要素の高さを見つける方法。しかし、それは私の問題ではうまくいかないでしょう。私のサイトでは、divの高さはtdの幅に依存する幅に依存します。これはページの幅に依存する他の行の状態とテーブルの幅に依存します。つまり、高さをあらかじめ計算していても、誰かが別の行を展開したり、ウィンドウのサイズを変更したりすると、値が間違ってしまうことになります。また、テーブルをコピーしてこれらの制約をすべて維持することは、ほぼ不可能に近いでしょう。

しかし、解決策が見つかりました。ユーザーがクリックして行を展開すると、次の手順が順番に実行されます。

  1. div.style.heightを1pxに設定します。
  2. row.style.displayをtable-rowに設定します。
  3. div.scrollHeightの値を格納します。
  4. div.scrollHeightで停止してスクロールアニメーションを実行します。
  5. アニメーションの後、div.style.heightをautoに設定します。

div.scrollHeight divの内容の高さ(オーバーフローを含む)を指定します。 divが表示されていないときは機能しませんが、アプリケーションで問題はありません。実際のコードのサンプルは次のとおりです。 (また、スクロールアニメーションのコードは長すぎるため、このコードは含まれていません。)

<!DOCTYPE HTML> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<style type="text/css"> 
table, td {border: 1px solid black;} 
#lower_row {display: none;} 
#lower_div {overflow: hidden;} 
</style> 
<script type="text/javascript"> 
function toggleLower() { 
    var lowerRow = document.getElementById("lower_row"); 
    var lowerDiv = document.getElementById("lower_div"); 
    if (getStyle(lowerRow, "display") == "none") { 
     lowerDiv.style.height = "0px"; 
     lowerRow.style.display = "table-row"; 
     showHeight(); 
     lowerDiv.style.height = "auto"; 
    } 
    else { 
     lowerDiv.style.height = "0px"; 
     showHeight(); 
     lowerRow.style.display = "none"; 
    } 
} 
function showHeight() { 
    var lowerDiv = document.getElementById("lower_div"); 
    document.getElementById("info").innerHTML = lowerDiv.scrollHeight; 
} 
// Return a style atribute of an element. 
// J/S Pro Techniques p136 
function getStyle(elem, name) { 
    if (elem.style[name]) { 
     return elem.style[name]; 
    } 
    else if (elem.currentStyle) { 
     return elem.currentStyle[name]; 
    } 
    else if (document.defaultView && document.defaultView.getComputedStyle) { 
     name = name.replace(/([A-Z])/g, "-$1"); 
     name = name.toLowerCase(); 
     s = document.defaultView.getComputedStyle(elem, ""); 
     return s && s.getPropertyValue(name); 
    } 
    else { 
     return null; 
    } 
} 
</script> 
</head> 

<body> 
<p>The height the lower row is currently <span id="info">...</span></p> 
<table> 
<tr id="upper_row" onclick="toggleLower()"><td><p>Click me to toggle the next row.</p></td></tr> 
<tr id="lower_row"><td><div id="lower_div"><p> 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
This is some long text. This is some long text. This is some long text. This is some long text. 
</p></div></td></tr> 
</table> 

</body> 
</html> 
+0

問題があるようですか?あなたのHTMLは正常に動作しています。行をクリックすると、下の行が展開されます。 –

+0

@vishal簡単にするために、私の例にはスライディングアニメーションがありません。スライドアニメーションを作成するには、拡大する前に高さを知る必要があります。私の例が示すように、拡大する前の高さは "auto"です。 – dln385

+0

@ dln385私のポストの私の更新を見てください –

答えて

14

あなたは、あなたが高さを計算し、DOMからクローンを削除することができ、それが目に見えるエリアの外になりますコンテンツをdiv要素をコピーして、絶対位置top:-10000; left:-10000;と体にそれを置くことができます。

UPDATE

また、あなたが動的な方法で要素を追加する場合は、あなたがdisplay:blockposition:absolute、そしてvisibility:hiddenに設定することができます - しかし、あなたはそれが任意の要素の位置を変更しないことを確認する必要がありますページ上にvisibility:hidden - 要素を示すが、それはあなたの特定のケースで

UPDATE

display: noneとは対照的に)寸法をだ計算あなたの要素のクローンを作成する必要があるので、あなたの親は、子供の大きさに影響を与えません。可視領域の外にある「類似の」親に変換する。 「類似」と言って、私はそれが同じ寸法を有するが、一般的にすべきである意味 - スタイルとそれの大きさに関係しているものすべてのもの:ここで

var wrapper = $('<div></div>').appendTo('body').css('display', 'block').css('position', 'absolute').css('top', -10000).css('left', -10000).css('width', $('table').css('width')); 
var clone = $('#lower_div').clone().appendTo(wrapper);  
document.getElementById("info").innerHTML = clone.height(); 

はあなたのためにjsfiddleを進めています。

+0

オーバーフローが隠されていないページについては、スクロールバーを簡単に表示しませんか? 'width:0;のiframeにスローするのはどうでしょうか?高さ:0; '? – Sorpigal

+0

いいえ、スクロールバーがページフローから外れるので、スクロールバーは表示されません。 Btw、同じスタイルをdivに適用することを忘れないでください。そのため、コピーの高さは正確に同じになります。 iframeは動作するかもしれませんが、重い/遅い解決策です。 –

+0

@Paul私はいずれかの解決策を得ることができません。私の編集を見てください。 – dln385

関連する問題