ホームページ > 記事 > ウェブフロントエンド > HTML CSS JSで主要ブラウザと完全互換のTABLE固定カラムを実現_JavaScriptスキル
BS アーキテクチャを備えたエンタープライズ レベルのアプリケーションでは、テーブルに多数の列がある場合、一般的なユーザーのニーズは最初のいくつかの重要な列を固定することです。このように、固定された列により、ユーザーはドラッグ時にデータを表示しやすくなります。スクロールバーのユーザーエクスペリエンスは素晴らしいです。一部の重量のある JS コンポーネント ライブラリにもこの機能がありますが、この機能を実現するより簡単な方法はありますか?
この要件に対する一般的な解決策は、テーブル スプライシング メソッドを使用することです。単純な関数を備えた静的 Web ページまたは動的ページを作成する場合、ロジックは比較的単純で、テクノロジも複雑ではありません。実装したいのですが、動的関数が多いと冗長なコードをたくさん書く必要があり、単純な関数でもイベント処理など多くのコードを書く必要があります。不器用で柔軟性が非常に低く、良い解決策ではありません。
長期間の分析と研究、およびさまざまなシナリオでの実験の結果、一般的に、位置決め計算方法を使用する非常に優れた解決策を見つけたので、以下にコードを掲載して説明します。
<!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> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题文档</title> <script type="text/javascript"> function divScroll(scrollDiv){ var scrollLeft = scrollDiv.scrollLeft; document.getElementById("tableDiv_title").scrollLeft = scrollLeft; document.getElementById("tableDiv_body").scrollLeft = scrollLeft; } function divYScroll(scrollYDiv){ var scrollTop = scrollYDiv.scrollTop; document.getElementById("tableDiv_y").scrollTop = scrollTop; } function onwheel(event){ var evt = event||window.event; var bodyDivY = document.getElementById("tableDiv_y"); var scrollDivY = document.getElementById("scrollDiv_y"); if (bodyDivY.scrollHeight>bodyDivY.offsetHeight){ if (evt.deltaY){ bodyDivY.scrollTop = bodyDivY.scrollTop + evt.deltaY*7; scrollDivY.scrollTop = scrollDivY.scrollTop + evt.deltaY*7; }else{ bodyDivY.scrollTop = bodyDivY.scrollTop - evt.wheelDelta/5; scrollDivY.scrollTop = scrollDivY.scrollTop - evt.wheelDelta/5; } } } </script> <style type="text/css"> body { margin:0; padding:0; } table { border-collapse:collapse; border:0; border:none; } table td { border:1px solid #000; overflow:hidden; padding:0 2px; } </style> </head> <body> <div style="width:500px; position:relative; padding-right:18px;"> <div style="position:relative;height:368px;overflow:hidden;width:100%"> <div style="padding-left:108px; width:auto; overflow:hidden; background:#f00;" id="tableDiv_title" > <table border="0" cellspacing="0" cellpadding="0" > <tr> <td style="min-width:30px; max-width:30px; left:0; top:0; width:30px; overflow:hidden; background-color:#f00;position:absolute;z-index:1;">000</td> <td style="min-width:74px; max-width:74px; left:30px; top:0; width:74px; overflow:hidden; background-color:#f00;position:absolute;z-index:1;">自动表格</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td> </tr> </table> </div> <div style="overflow:hidden; position:absolute;height:128px; width:100%;" id="tableDiv_y" onmousewheel="onwheel(event);" onwheel="onwheel(event);"> <div style="padding-left:108px; width:auto;overflow:hidden;" id="tableDiv_body"> <table border="0" cellspacing="0" cellpadding="0" > <tr> <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">001</td> <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">自动表格</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td> </tr> <tr> <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff; position:absolute; z-index:1;">002</td> <td style="min-width:74px; max-width:74px; left:30px; width:74px; overflow:hidden;background-color:#fff; position:absolute; z-index:1;">自动表格</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td> </tr> <tr> <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">003</td> <td style="min-width:74px; max-width:74px;left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td> </tr> <tr> <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">004</td> <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td> </tr> <tr> <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">005</td> <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td> </tr> <tr> <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">006</td> <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td> </tr> <tr> <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">007</td> <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td> </tr> <tr> <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">008</td> <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td> </tr> <tr> <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">009</td> <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td> </tr> <tr> <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">010</td> <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td> <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td> </tr> </table> </div> </div> <div style="background-color:#eee;overflow:hidden;top:150px; width:100%; z-index:2;position:absolute;"> <div style="margin-left:108px; width:auto;overflow-x:scroll;overflow-y:hidden;" onscroll='divScroll(this);'> <div style="width:630px; height:1px;"></div> </div> </div> </div> <div id="scrollDiv_y" style="display:block; overflow-x:hidden; overflow-y:scroll; position:absolute; top:22px; right:0px; height:118px; padding-bottom:10px;" onscroll='divYScroll(this);'> <div style="width:1px; height:194px;"></div> </div> </div> </div> </body> </html>
1. 全体の構造:
ページの基本要素は DIV TABLE です。固定列は絶対位置によって固定されます。水平スクロール バーと垂直スクロール バーの問題を解決するには、テーブルのヘッダーと本文が固定幅を指定する必要があります。バーはそれぞれ 2 つの DIV レイヤーでラップされており、JS コントロールを通じて固定位置に固定され、通常の DIV スクロール バーの効果をシミュレートします。
2. ポジショニング:
固定列は絶対的に配置する必要があり、左の移動は left 属性によって制御されます。固定列が確実に上に浮くようにするには、z-index を 1 に設定します。垂直スクロール バーがあるときに正常に表示されるようにするには、テーブル本体の外側の DIV が絶対位置に設定されるため、スクロール バーも絶対位置に設定する必要があります。さらに、テーブル ヘッダー、テーブル本体、およびスクロール バーの内部 DIV は、margin-left 属性を使用して左マージンを制御し、固定列のオフセットを自由のままにします。
2. 幅の計算:
各列の幅は固定値で指定する必要があり、重要な点に注意する必要があります。つまり、これら 2 つの属性は幅の値と同じである必要があります。ヘッダーと本文のレイヤー DIV の内容、幅は自動、アダプティブ テーブル幅、外側の DIV 幅は 100%、最も外側の DIV は、padding-right 属性によって右内側のマージンを制御し、垂直スクロール バーの位置は自由なままにします。
3. 高さの計算:
絶対位置指定が存在するため、テーブル コンポーネント全体の高さを指定する必要があり、垂直スクロール バーの上部の値も計算する必要があります。
4. スクロールバー:
このソリューションの顕著な機能は、テーブル本体 DIV の水平スクロール バーを、テーブルと同じ幅と 1 ピクセルの高さの DIV でシミュレートする仮想スクロール バーです。これは垂直スクロール バーにも当てはまります。スクロールバー。この形式を採用する理由は、垂直スクロールバーをこのように処理すると、テーブルヘッダーとテーブル本体の外側の DIV 幅を計算する必要がなくなるためです。それ以外の場合、スクロール バーがある場合、テーブルのヘッダーは水平スクロール バーから垂直スクロール バーの幅の移動を解放する必要があります。そうしないと、位置を合わせることができません。この計算は複雑ではありません。場合によっては問題が生じることがありますが、ここでは詳しく説明しません。
5. スクロールイベント:
テーブル本体のスクロール バーが非表示になっているため、マウス ホイールが機能しません。このため、JS を使用してマウス ホイール イベントを処理する必要があります。この記事のサンプル コードは一般的なブラウザーと互換性があります。ここで重要なのは、onmousewheel と onwheel イベントが同時に書き込まれることです。onmousewheel は IE と互換性があります。スクロール距離を計算するときは、deltaY 属性と WheelDelta 属性の違いに注意してください。
6. 利点と欠点の分析:
この記事の解決策は、現実では非常に複雑であることを明確に説明することに重点を置いています。この設計では、ブラウザーの互換性やさまざまなシナリオでの互換性など、多くの互換性が考慮されています。要件が単純であれば、簡素化の余地があります。
このソリューションの利点は、HTML 構造が単純でテーブル ヘッダーとテーブル本体が両方とも TABLE であるため、コンポーネントを作成する場合、JS コントロール コードが非常にクリーンで保守が容易であることです。欠点は計算量が多すぎることです。このソリューションはコンポーネントの開発により適していると考えており、静的ページは少し面倒です。
以上がこの記事の全内容です。皆さんに気に入っていただければ幸いです。