1

長いHTMLテーブルがあり、スクロールからヘッダーを修正する必要があります。それを行うための多くのプラグインとトリックを見つけましたが、どれもうまくいきませんでした。

私にとって何もうまくいかない理由は次のとおりだと思いました:

  1. すべてのソリューションは、テーブルからヘッダーを切り離します
  2. コンテンツの上にヘッダーを保持するために、すべての列に固定幅を使用します
  3. 私のテーブルは非常に応答性が高く、可能な限り全幅を取得するために伸びます ( width=100%)

誰か提案はありますか?

ashley編集: CSSテクニックを更新したおかげで

私の hmlt テーブルは次のようになります: http://jsfiddle.net/enPZP/4/

4

4 に答える 4

3

私は問題に対してかなり良い解決策を思いついたと思います.それは私が望んでいたよりも少し深いものですが、結果には本当に満足しています.

ここに画像の説明を入力

それが機能する方法は、ドキュメントの準備ができており、テーブルヘッダーを複製し、複製のサイズをテーブルヘッダーのサイズに設定し、それを他のヘッダーの上に配置します。スクロール時に、ウィンドウの上部がテーブルの上部より下にある場合、クローンtopがウィンドウの上部になるように設定します。サイズを変更すると、<th>サイズが再計算されます。

<th>s を とは<thead>別に配置したことに注意してください。

jsフィドル

var tableBaseTop;
var originalHeader;
var floatingHeader;

$(document).ready(function () {
    tableBaseTop = $('table th').offset().top;
    originalHeader = $('thead');
    floatingHeader = originalHeader.clone();
    floatingHeader
        .css('position', 'absolute')
        .css('top', 0);

    setFloatingHeaderSize();

    $('table').prepend(floatingHeader);

    $(window).scroll(function () {
        var windowTop = $(window).scrollTop();

        if (windowTop > tableBaseTop)
            floatingHeader.css('top', windowTop - tableBaseTop);
        else
            floatingHeader.css('top', 0);
    });

    $(window).resize(setFloatingHeaderSize);
});

function setFloatingHeaderSize() {
    var originalThs = originalHeader.find('th');
    var floatingThs = floatingHeader.find('th');
    for (var i = 0; i < originalThs.length; i++) {
        floatingThs.eq(i)
            .css('width', originalThs.eq(i).width())
            .css('height', originalThs.eq(i).height());
    }
}

Firefox ヘッダー幅の問題

問題を解決することはできましたが、jQuery のヘルパーを使用してそれを行う方法がわかりませんでした。問題は、実際の幅/高さが小数であり、浮動小数点として必要な場合に、jQuery が整数サイズを提供していたことです。これは、動作するフィドルで変更したコードのセクションです。

jsフィドル

function setFloatingHeaderSize() {
    var originalThs = originalHeader.find('th');
    var floatingThs = floatingHeader.find('th');
    for (var i = 0; i < originalThs.length; i++) {
        var padding = 
            parseFloat(window.getComputedStyle(this.originalThs[i], null).getPropertyValue('padding-left').replace('px', ''), 10) +
            parseFloat(window.getComputedStyle(this.originalThs[i], null).getPropertyValue('padding-right').replace('px', ''), 10);

        floatingThs.eq(i)
            .css('width', this.originalThs[i].offsetWidth - padding)
            .css('height', this.originalThs[i].offsetHeight - padding);
    }
}

更新: ソリューションを思いついた直後に、これを再利用可能なライブラリにしました。GitHub で表示してください。

于 2013-03-28T16:32:09.513 に答える
0

固定高さの列ヘッダーが受け入れられる場合、この問題は純粋な CSS で解決できます。

OPのテーブルと同じように、流動的なテーブル幅と自動列幅で構成された例を次に示します: jsFiddle

この例では、垂直スクロールバーは必要な場合にのみ表示されることに注意してください。表示するには、フレームのサイズを変更する必要がある場合があります。

以下のコードはフィドルと同じですが、テーブルの高さが固定されています。指定された高さを超える十分な行がある限り、スクロールバーは常にその構成で表示されます。

HTML

<div class="scrollingtable">
  <div>
    <div>
      <table>
        <caption>Top Caption</caption>
        <thead>
          <tr>
            <th><div label="Column 1"/></th>
            <th><div label="Column 2"/></th>
            <th><div label="Column 3"/></th>
            <th>
              <!--more versatile way of doing column label; requires 2 identical copies of label-->
              <div><div>Column 4</div><div>Column 4</div></div>
            </th>
            <th class="scrollbarhead"/> <!--ALWAYS ADD THIS EXTRA CELL AT END OF HEADER ROW-->
          </tr>
        </thead>
        <tbody>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
        </tbody>
      </table>
    </div>
    Faux bottom caption
  </div>
</div>

CSS

<!--[if lte IE 9]><style>.scrollingtable > div > div > table {margin-right: 17px;}</style><![endif]-->
<style>
/*the following html and body rule sets are required only if using a % width or height*/
html {
  width: 100%;
  height: 100%;
}
body {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0 20px 0 20px;
    text-align: center;
}
.scrollingtable {
  box-sizing: border-box;
  display: inline-block;
  vertical-align: middle;
  overflow: hidden;
  width: auto; /*if you want a fixed width, set it here, else set to auto*/
  min-width: /*0*/100%; /*if you want a % width, set it here, else set to 0*/
  height: /*188px*/100%; /*set table height here; can be fixed value or %*/
  min-height: /*0*/104px; /*if using % height, make this large enough to fit scrollbar arrows + caption + thead*/
  font-family: Verdana, Tahoma, sans-serif;
  font-size: 16px;
  line-height: 20px;
  padding: 20px 0 20px 0; /*need enough padding to make room for caption*/
  text-align: left;
}
.scrollingtable * {box-sizing: border-box;}
.scrollingtable > div {
  position: relative;
  border-top: 1px solid black;
  height: 100%;
  padding-top: 20px; /*this determines column header height*/
}
.scrollingtable > div:before {
  top: 0;
  background: cornflowerblue; /*header row background color*/
}
.scrollingtable > div:before,
.scrollingtable > div > div:after {
  content: "";
  position: absolute;
  z-index: -1;
  width: 100%;
  height: 100%;
  left: 0;
}
.scrollingtable > div > div {
  min-height: /*0*/43px; /*if using % height, make this large enough to fit scrollbar arrows*/
  max-height: 100%;
  overflow: /*scroll*/auto; /*set to auto if using fixed or % width; else scroll*/
  overflow-x: hidden;
  border: 1px solid black; /*border around table body*/
}
.scrollingtable > div > div:after {background: white;} /*match page background color*/
.scrollingtable > div > div > table {
  width: 100%;
  border-spacing: 0;
  margin-top: -20px; /*inverse of column header height*/
  margin-right: 17px; /*uncomment if using % width*/
}
.scrollingtable > div > div > table > caption {
  position: absolute;
  top: -20px; /*inverse of caption height*/
  margin-top: -1px; /*inverse of border-width*/
  width: 100%;
  font-weight: bold;
  text-align: center;
}
.scrollingtable > div > div > table > * > tr > * {padding: 0;}
.scrollingtable > div > div > table > thead {
  vertical-align: bottom;
  white-space: nowrap;
  text-align: center;
}
.scrollingtable > div > div > table > thead > tr > * > div {
  display: inline-block;
  padding: 0 6px 0 6px; /*header cell padding*/
}
.scrollingtable > div > div > table > thead > tr > :first-child:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 20px; /*match column header height*/
  border-left: 1px solid black; /*leftmost header border*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div > div:first-child,
.scrollingtable > div > div > table > thead > tr > * + :before {
  position: absolute;
  top: 0;
  white-space: pre-wrap;
  color: white; /*header row font color*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div[label]:after {content: attr(label);}
.scrollingtable > div > div > table > thead > tr > * + :before {
  content: "";
  display: block;
  min-height: 20px; /*match column header height*/
  padding-top: 1px;
  border-left: 1px solid black; /*borders between header cells*/
}
.scrollingtable .scrollbarhead {float: right;}
.scrollingtable .scrollbarhead:before {
  position: absolute;
  width: 100px;
  top: -1px; /*inverse border-width*/
  background: white; /*match page background color*/
}
.scrollingtable > div > div > table > tbody > tr:after {
  content: "";
  display: table-cell;
  position: relative;
  padding: 0;
  border-top: 1px solid black;
  top: -1px; /*inverse of border width*/
}
.scrollingtable > div > div > table > tbody {vertical-align: top;}
.scrollingtable > div > div > table > tbody > tr {background: white;}
.scrollingtable > div > div > table > tbody > tr > * {
  border-bottom: 1px solid black;
  padding: 0 6px 0 6px;
  height: 20px; /*match column header height*/
}
.scrollingtable > div > div > table > tbody:last-of-type > tr:last-child > * {border-bottom: none;}
.scrollingtable > div > div > table > tbody > tr:nth-child(even) {background: gainsboro;} /*alternate row color*/
.scrollingtable > div > div > table > tbody > tr > * + * {border-left: 1px solid black;} /*borders between body cells*/
</style>

OP の表とまったく同じようにするには、背景色を変更し、境界線を削除する必要があります。これらのタイプの変更を行うための指示は、CSS コメントにあります。

別の構成については私の回答を確認してください。ヘッダー行を固定するために使用される基本的な手法の説明については、同じ投稿の d-Pixie の回答を確認してください。

于 2014-09-15T14:36:11.057 に答える
0

先頭行を別のテーブルに分けて、いくつかの jquery コードを追加します。

html:

<table class="headtable">
<tr>
    <td>name</td>
    <td>value</td>
    <td>action</td>
</tr>
</table>
<div class="scrolltable">
    <table class="valuetable">
        <tr>
            <td>hay 1</td>
            <td>1</td>
            <td>edit</td>
        </tr>
<tr>
            <td>hay 1</td>
            <td>1</td>
            <td>edit</td>
        </tr>
        <tr>
            <td>hay 1</td>
            <td>1</td>
            <td>edit</td>
        </tr>
        <tr>
            <td>hay 1</td>
            <td>1</td>
            <td>edit</td>
        </tr>
        </table>
</div>

js コード:

$('.headtable tr').children().each(function(index)
    {      
      $(this).width($('.valuetable tr:first td').eq(index).width());
    });

必要に応じてスタイル:

.scrolltable{height:500px; overflow:auto;}

自動サイズ変更(レスポンシブ)が必要な場合:

$(window).resize(function(){
$('.headtable tr').children().each(function(index)
        {      
          $(this).width($('.valuetable tr:first td').eq(index).width());
        });
});
于 2013-03-28T16:15:10.293 に答える
0

これでフィドルを修正しました。これにより、ヘッダーがグリッドの上部に固定されます。ただし、タイルを左上に固定するという欠点があります。

うまくいけば、これは完全な答えへの道のりに役立ちます.

table {
    width: 100%;
    border-collapse: collapse;
    position: relative;
}
div.scoll {
    overflow: scroll;
    height: 300px;
}
.center {
    text-align: center;
}
thead {
    position: static;
    width: 100%;
}
thead tr {
    position: fixed;
}

htmlを次のように変更しました

<div class="scoll">
<table>
        <thead>
            <tr>
                <th>Code</th>
                <th>Rank</th>
                <th>Code</th>
                <th>Icon</th>
                <th>Message Text</th>
                <th>Progress</th>
                <th>Current</th>
                <th>X</th>
                <th>Y</th>
                <th>Z</th>
                <th>W</th>
                <th>Result</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td colspan="12">&nbsp;</td>
            </tr>
            <tr class="data-row" id="19">
                <td class="center">DDD</td>
                <!-- 4 alpha numeric -->
                <td class="center">111</td>
                <!-- 3 digits -->
                <td class="center">222</td>
                <!-- 3 digits -->
                <td class="center">
                    <img width="20" height="20" src="http://cdn1.iconfinder.com/data/icons/CrystalClear/128x128/apps/ark2.png">
                    <!-- icon -->
                </td>
                <td>Lorem ipsum</td>
                <!-- text may be long -->
                <td class="center">333</td>
                <!-- 3 alpha numeric -->
                <td class="center">444</td>
                <!-- 3 alpha numeric -->
                <td class="center">555</td>
                <!-- 3 alpha numeric -->
                <td class="center">666</td>
                <!-- 3 alpha numeric -->
                <td class="center">777</td>
                <!-- 3 alpha numeric -->
                <td class="center">888</td>
                <!-- 3 alpha numeric -->
                <td class="center">999</td>
                <!-- 3 alpha numeric -->
            </tr>
</tbody>
</table>
</div>
于 2013-03-28T16:09:37.473 に答える