テーブルのヘッダー(上部と左部)を固定してスクロールさせる方法

# はじめに
管理画面などでデータの表示にテーブルタグを使うことはよくありますよね。
その際表示したい項目数が多いと当然スクロールさせることになりますが、スクロールさせるとヘッダー部が見えなくなるのでどのデータが何を表しているのか大変分かりづらくなります。

すると、ヘッダーを固定させたくなります。
なのでこの記事ではヘッダーを固定させてスクロールさせる方法を調査して実装してみたのでご紹介していきます。
固定するにしても上部と左部の両方を固定させる方法を調べました。

# 実現方法
まずはどうしたら実現できるかですが、方法はざっくり2つに別れます。

- CSSとjQuery(JavaScript)で自前で実装する
- jQuery(JavaScript)のプラグインを利用する

自前で実装するメリットとしてはおかしい挙動があった際に自分で書いたコードだからデバッグしやすい。そのかわり実装に時間がかかってしまう。
プラグインを使えば実装はしやすいがデバッグがしづらくなってしまいます。

今回はさっと時間をかけずに実現したいのでプラグインを利用することにします。


# プラグイン
どのようなプラグインがあるのか調べたところたくさん出てきました。

- [jquery.fixedTblHdrLftCol](https://github.com/nkmrshn/fixedTblHdrLftCol)
	- 最終更新が2014年6月
- [fixedMidashi](http://hp.vector.co.jp/authors/VA056612/fixed_midashi/manual/index.html)
	- 最終更新が2015年11月
- [jquery.tablefix.js](https://github.com/yoshitsugu/tablefix)
	- 最終更新が2015年11月
- [jquery.fixedheadertable.js](https://github.com/markmalek/Fixed-Header-Table/commits/master)
	- 最終更新が2014年5月
- [Grid](https://github.com/mmurph211/Grid)
	- 最終更新が2013年2月
- [jquery.fixedTableHeader](https://github.com/hungnq1989/fixed-table-header)
	- 最終更新が2014年11月
- [jquery.floatThead](https://github.com/mkoryak/floatThead)
	- 最終更新が2016年1月

しかしどうやら上部のみ固定のものが多いようです。
またもっと探せばまだまだたくさん見つかる気もします。

上記の中でも上と横の両方を固定できそうだったのが
`jquery.fixedTblHdrLftCol`、`fixedMidashi`、`jquery.tablefix.js`、 `Grid`
になります。


`Grid`は固定するだけでなく自由にテーブルの表示サイズを変えれることもでき多機能でした。
それ以外は導入のしやすさ、使えるオプションもあまり変わらないようでした。
なのであまり深い意味はなく`fixedMidashi` を使うことにしました。

ちなみに縦のみのスクロールだと `jquery.floatThead` が良さそうです。

# テーブル表示
導入したところ実際の表示は以下のようになりました。
縦と横の両方のスクロールができるようになります。

![FixTableHeaderSample.png](https://qiita-image-store.s3.amazonaws.com/0/41362/112a222f-2a67-584b-089c-ed65e2ef63fd.png "FixTableHeaderSample.png")

# 導入方法
導入の際に以下の技術を利用しています。
言語: `Ruby`
フレームワーク: `Ruby on Rails`
ビュー: `haml`
JavaScript: `CoffeeScript`

## プラグインのダウンロード
まず下記ページからダウンロードをして `vendor/assets/javascripts` 配下にプラグインファイルを置きます。
[http://www.vector.co.jp/soft/other/java/se498696.html](http://www.vector.co.jp/soft/other/java/se498696.html)

Vectorのサイトからダウンロードというのが少し気になりますね。

## application.js.coffee
下記の1文を追加して利用できるようにします。
プラグイン自体はjQueryは使用していません。

```
#= require fixed_midashi_src
```


## ビュー
次にビューは以下の通りです。

```haml
.scroll_div{ style: 'overflow: auto;width: 500px'}
  %table{ _fixedhead: 'rows:1; cols:1', style: 'width: 700px' }
    %thead
      %tr
        %th
        %th ヘッダー1
        %th ヘッダー2
        %th ヘッダー3
        %th ヘッダー4
        %th ヘッダー5
    %tbody
      %tr
        %td ヘッダーA
        %td あああ
        %td いいい
        %td ううう
        %td えええ
        %td おおお
      %tr
        %td ヘッダーB
        %td あああ
        %td いいい
        %td ううう
        %td えええ
        %td おおお
      ...
```

ポイントは、先頭の2行になります。

```haml
.scroll_div{ style: 'overflow: auto;width: 500px'}
  %table{ _fixedhead: 'rows:1; cols:1', style: 'width: 700px' }
```

`.scroll_div` クラスで `table` タグを囲んで `_fixedhead` 属性に
固定したい行数や列数を指定することができます。

`table` タグを `div` タグで囲むことで対象 `table` の親 `div` のスクロールに対して固定見出しを制御するようになります。
他には `body` のスクロールに対して固定見出しを制御することもできます。

詳しくは下記ページを参照下さい。
[FixedMidashi トップページ](http://hp.vector.co.jp/authors/VA056612/fixed_midashi/manual/index.html)

またCSSを直接ビューに書いていますが、クラスを指定して別ファイルにCSSは定義するようにしましょう。


## CoffeeScript

JS側は以下の1行を追加するだけになります。

```
FixedMidashi.create()
```

以上でヘッダー部を固定したテーブルを表示することができます。


# 動作確認したブラウザ
そして開発者としては気になるのはどのブラウザで動くのかということですよね。
JavaScriptで色々ゴニョゴニョさせると特定のブラウザだけ動きがおかしい！
とかよくはまりますよね。。特にIEとか。

なので下記の主要なブラウザで動作を確認することができました。

## Mac
Chrome 48.0
Safari 9.0.3
Firefox 44.0.2

## Windows
Chrome 48.0
IE 11.0
(すみませんIE11より下は試していません。。IETesterにてIE6-9では動きました。)

## iPhone
Safari 601.1
Chrome 48.0

問題なさそうでした。


# まとめ
以上のようにテーブルのヘッダー部を固定してスクロールさせることはやはりプラグインを使えば簡単に実装できることがわかりました。自前で実装するよりは全然楽です。
またプラグインの数も豊富で、頻繁にはコードは更新していないようですが数年前から更新されていない。ということもないようでした。

自前で実装した場合にどのようなコードになるのか考えてみる。
あるいはプラグインがどのようなロジックで実現しているのかを見てみるのかしてみるのも面白そうだなと思いました。