[jQuery] テーブルのヘッダを固定する

検索しても、テーブルのヘッダを固定して、
ウィンドウ側のスクロールで移動するものが見つからなかったので作ってみた。
(疑似インラインフレームが多い)

ただし、簡単なサンプルを作った時点で不採用となったので
バグや動作を精査する必要がなくなりました。ですので、あくまで参考としてください。

問題点:
※ 横スクロールでずれる。
※ テーブルの内容(TD)に文字列以外(INPUTなど)が含まれると崩れる
※ テーブルのヘッダを調整するスクリプトの部分が不完全
  (1列しか対応してないので何個も同じコードを書く必要がある)
モダンブラウザなら動作するかと…。一応、IE9とFirefoxで動作確認済み

以下、コードです。

HTML

<table id="fixedtest">
	<tr>
		<th rowspan="2">地区</th>
		<th rowspan="2">建物</th>
		<th colspan="3">上期</th>
		<th colspan="3">下期</th>
	</tr>
	<tr>
		<th>予定単価</th>
		<th>発生単価</th>
		<th>発生差額</th>
		<th>予定単価</th>
		<th>発生単価</th>
		<th>発生差額</th>
	</tr>
		<tr class="fixedData">
		<td><div id="chikuHide"></div></td>
		<td></td>
		<td></td>
		<td></td>
		<td></td>
		<td></td>
		<td></td>
		<td></td>
	</tr>
</table>

<table id="resultTable">
	<tr>
		<th rowspan="2">地区</th>
		<th rowspan="2">建物</th>
		<th colspan="3">上期</th>
		<th colspan="3">下期</th>
	</tr>
	<tr>
		<th>予定単価</th>
		<th>発生単価</th>
		<th>発生差額</th>
		<th>予定単価</th>
		<th>発生単価</th>
		<th>発生差額</th>
	</tr>
	<tr class="resultData">
		<td>hoge</td>
		<td></td>
		<td>hoge</td>
		<td>hoge</td>
		<td></td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
	</tr>
	
	<tr class="resultData">
		<td>hoge</td>
		<td>hogehogehogehogehogehogehoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
	</tr>
	
	<tr class="resultData">
		<td>hogehogehoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
	</tr>
	
	<tr class="resultData">
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
	</tr>
	
	<tr class="resultData">
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
	</tr>
	
	<tr class="resultData">
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
		<td>hoge</td>
	</tr>
	<!-- 省略 -->
</table>

jQuery

$(function() {
	cols = $("#resultTable tr").size();
	for (i = 0; i < cols; i++) {
		var tmp = 0;
		var max = 0;
		$("#resultTable").each(function() {
			tmp = $("#resultTable td:eq(1)").width();

			if (parseInt(tmp, 10) > parseInt(max, 10)) {
				max = tmp;
			}
		});
		$("#chikuHide").css('width', max);
	}
	
	var trtest = $("#fixedtest");
	trtest.hide();
	$(window).scroll(function() {
		if ($(this).scrollTop() > 100) {
			trtest.fadeIn();
		} else {
			trtest.fadeOut();
		}
	});
});

CSS

#fixedtest{
	top:0;
	position: fixed;
	display: none;
}

#fixedtest td{
	background-color: transparent;
}
tr.fixedData ,
tr.fixedData td {
	border:1px solid transparent;
}

#chikuHide {
	margin:0;
	padding:0;
	height:0;
}

解説

<table id="resultTable">がメインのテーブルで、
「#resultTableのヘッダと<tr>一行」をコピーした<table id="fixedtest">が固定されるヘッダになります。

#resultTable の指定の列(ここでは"地区")から最大文字数の文字列を取得して
#fixedtest の対応する#chikuHideに同じ文字列を挿入します。

要は、固定用のヘッダ(テーブル)と元のテーブルのカラムが同じ幅になれば良いわけです。

#fixedtest は隠しておいて、一定のスクロールで表示させるようにします。
あらかじめ #fixedtest 内の<td>の罫線や文字列はtransparentで見えないようにしておきます

text-indent:100%;
white-space:nowrap;
overflow:hidden;

でもいいかも…

以上でヘッダの固定ができるはず…
色々と問題点がありますが、あくまで参考としてどうぞ…

twitterfacebookhatenafacebook