HTML+CSS+JSは、各ブラウザを完璧に兼ね備えたTABLE固定列を実現します。

16931 ワード

BSアーキテクチャの企業レベルアプリケーションでは、テーブルの列数が多いとき、ユーザーの共通の需要は前のいくつかの重要な列を固定することです。このようにスクロールバーをドラッグすると、固定された列はユーザーがデータを見やすくなり、ユーザーが体験するのが良いです。いくつかのヘビー級のJSコンポーネントライブラリにもこの機能がありますが、もっと簡単な方法でこの機能を実現できますか?
このよくある解決策は表のつなぎ合わせを使う方法です。この方案は静的なホームページを作るか、あるいは機能が簡単な動的ページを作るなら、論理が簡単で、技術的にも複雑ではなく、実現しやすいです。多くのコードを書く必要があります。例えば、事件の処理など、この方法は不器用で、柔軟性が悪く、いい案ではありません。
長い間の分析研究を経て、様々なシーンのテストを行い、互換性の高い解決策を見つけました。全体としては定位計算の方法を採用しています。下記にコードを貼り付けて、解読します。

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


一、全体構造:
            ページの基本的な要素はDIV+TABLEで、固定された列は絶対的な位置付けの方式で固定されています。各列は固定幅を指定して、縦横スクロールバーの問題を解決するために、表頭と表体の外はそれぞれ2層のDIVを包んで、スクロールバーは仮想的な方式を採用して、固定位置に固定してJS制御で正常なDIVスクロールバーの効果を模擬します。
二、位置決め:
            固定された列は絶対的に位置決めし、left属性によって左側の変位を制御し、固定列が上に浮動することを保証するために、z-indxを1に設定します。縦スクロールバーがある時の正常な表示を保証するために、表の外層DIVは絶対的な位置決めとなり、スクロールバーも絶対的に位置決めします。また、表头と表体とスクロールバーの内部层DIVは、margin-left属性によって左の外侧の距离を制御し、固定列のオフセット量を空间にします。
二、幅計算:
            各列の幅は固定された値を指定し、重要な点として、min-width属性とmax-width属性を加えます。この二つの属性はwidth値と同じで、表頭体の内部層DIV、幅はaut、適応表の幅は、外層DIVの幅は100%で、最外層のDIVはpadding-right属性を通じて、右側の内側のマージンを制御します。縦スクロールバーの位置を空けます。
三、高さの計算:
            絶対位置の存在によって、テーブルのコンポーネント全体の高さを指定します。計算することによって、縦スクロールバーのtop値も計算されます。
四、スクロールバー:
            このスキームの特徴は、仮想スクロールバーです。つまり、表と同じ幅、高さがピクセルのDIVを通して、表体DIVの横スクロールバーをシミュレートします。縦スクロールバーは同じです。この形式を採用したのは、一つは横スクロールバーです。このように処理すると、縦スクロールバーはより綺麗で、その後、表頭と表体の外層DIV幅は計算しなくてもいいです。全部100%です。でないと、スクロールバーが存在する場合、表頭と横スクロールバーは縦スクロールバーの幅の変位を空けなければなりません。ここでは展開しません。
五、スクロールイベント:
            表体のスクロールバーがすべて隠れているため、マウスホイールが機能しなくなり、JSでマウスホイールのイベントを処理する必要があります。本記事のサンプルコードはよく見るブラウザに対応しています。ここのポイントは同時にonmousewheelとonwheel事件を書いたので、onmouseweheel互換IE、転がり距離を計算する時、deltaYとwheelDelta属性の違いに注意すればいいです。
 六、長所と短所の分析:
            本論文の解決策は既に簡略化されており、原理を明確に説明することに重点を置いており、我々の実際においては、非常に複雑である。この設計は、ブラウザの互換性と様々なシーンの互換性を含めた非常に多くの互換性を考慮しています。
            この案の利点は、コンポーネントを作るならば、HTML構造が簡単で、表面と表面は同じTABLEであり、JS制御コードが非常に清潔で、メンテナンスが容易であることです。欠点は計算が多すぎることです。この方式は開発部品の場合に適していると思います。静的ページはちょっと大げさです。
以上述べましたが、本文の内容は全部です。お好きになってください。