ガレコレ
Garage Collection
 
2016年4月24日(日)
表のウインドウ枠の固定 #HTML5&CSS3&JavaScript

 Excel(表計算ソフト)において『表のウインドウ枠の固定』はよく使う機能ですが、HTMLの世界においてコマンドレベルでは用意されていません。

 列見出しと行見出しを固定する方法は、色々なやり方が考えられます。4つの窓方式が、一番自然ですね。

┌div 全体────────────┐
│       ┌div 列見出し─┐│
│ ┌table ┐ │┌table ──┐││
│ │ 固定 │ ││ 横scroll │││
│ │    │ ││ (連動) │││
│ │    │ ││ ← → │││
│ └───┘ │└─────┘││
│ div     └───────┘│
│┌ 行見出し ┐┌div データ──┐│
││┌table ┐││┌table ──┐││
│││縦  ││││縦横scroll│││
│││scroll││││     │││
│││ ↑ ││││  ↑  │││
│││(連動)││││ ← → │││
│││ ↓ ││││  ↓  │││
││└───┘││└─────┘││
│└─────┘└───────┘│
└────────────────┘



 スケジューラーのプログラムを例に説明します。プログラムは、結構長いので、ブラウザの[ソースの表示]等で、ご確認下さい。

 デバイス判別して、全体表示枠とデータ表示枠を三通りに調整しています。スクロールバー表示の有無、および、スクロールバー幅の差を吸収するためです。まあ、事実上、この機能は小さな画面であるスマホ用なので、ブラウザ分岐処理は不必要でしょう。なお、古いブラウザでは上手く機能しませんので、あしからず。

(1) iPhone(Safari)、Android(Google Chrome)
 スクロールバー無し 0px
(2) Windows版Microsoft Edge
 スクロールバー幅 12px
(3) Windows版Google Chrome、Windows版IE11、および、その他
 スクロールバー幅 17px


 まずは、CSS3(スタイルシート)における設定です。サイズ指定した大きさからのはみ出た部分(オーバーフロー)を、列見出しと行見出しは隠して(非表示)、データはスクロールバーで対応します。
 
--ヘッダー部分の<div>のstyle--
overflow-x:hidden;
overflow-y:hidden;
--

--データ部分の<div>のstyle--
overflow-x:scroll;
overflow-y:scroll;
--


 JavaScriptで、データが縦横スクロールした分だけ、列見出しと行見出しをスクロールさせています。

--JavaScript--
<script>

function _scroll(){
  document.getElementById("area_column").scrollLeft = document.getElementById("area_data").scrollLeft;

  document.getElementById("area_row").scrollTop = document.getElementById("area_data").scrollTop;
}

</script>
--

--HTML5--
<div id="area_column">
<table id="table_column">
 …省略…
</table>
</div>

<div id="area_row">
<table id="table_row">
 …省略…
</table>
</div>

<div id="area_data" onscroll="_scroll();">
<table id="table_data">
 …省略…
</table>
</div>
--

 HTML5において、JavaScriptのonScrollイベントハンドラーは、windowに対しては有効ですが、各オブジェクトに対しては誤った記述となります。オブジェクトの場合は、タグ内に記述すると正常に動作します。

--

<div id="area_data" onscroll="_scroll();">

×
<script>
document.getElementById("area_data").onscroll=_scroll;
</script>

<div id="area_data">…省略…</div>
--


 まあ、一番煩雑なのは、表示エリアのleft,top,width,heightとテーブルのwidth,heightをしっかり指定する作業ですね。

 今回の寸法は、下記の通り。スマホでは、表示幅400pxで表示します。データ部分のセル幅を110pxに固定して、三人分を同時に表示します。枠固定の境界を二重線にするために、わざわざ1pxずらしています。

--
<meta name="viewport" content="width=400px">

<style>
.cell {width:110px;}
</style>
--

┌div 387 ──────────┐
│       (57,0)    │
│ (0,0)    ┌div 330 ─┐│
│ ┌table ┐ │┌table ┐57│
│ │ 56 │ ││ 1650 │││
│ │   57 ││(連動)57││
│ │    │ ││← →│││
462 └───┘ │└───┘││
│       └─────┘│
│(0,58)    (57,58)    │
│┌div 56──┐┌div 330 ─┐│
││┌table ┐404 ┌table ┐404
│││ 56 ││││ 1650 │││
│││ ↑ *│││ ↑ *││
│││(連動)││││← →│││
│││ ↓ ││││ ↓ │││
││└───┘││└───┘││
│└─────┘└─────┘│
└──────────────┘
*は、データ内容によって変化するので、未指定。
※スクロールバーが表示されるブラウザでは、スクロールバー幅を加味します。


 なお、サンプルでは、スケジュールデータを発生させて、複雑なこともやっていますが、無視して下さい。曜日はプログラムの簡略化のため、現実と合っていませんので、あしからず。



P.S. 世の中には、汎用化したJavaScriptライブラリがあり、試させてもらいましたが、『表のウインドウ枠の固定』に関しては、あまり使い物にならないですね。


P.S.2 HTML5とCSS3では、<table>タグを異常に嫌っていますが、やはり表組には便利なタグです。まあ、ブラウザでの表示が遅くなるので、レイアウト目的には使わない方が賢明ですが。。。


P.S.3 スマホAndroidでの動作確認に、友人の京セラTORQUE(トルク)を拝借させてもらいましたが、スクロール処理にもたついていました。頑丈さが売りのものなので、筋肉バカなのかな。結構、塗料が剥げていたので、またまた割らないでねと祈っています。


P.S.4 アドレスに、アンカーリンクを何も指定しないと、自動的に今日の日(曜日は無視してね)にスクロールします。アンカーリンクを入力すると、そこまでスクロールして、指定セルを見えるようにします。

--
アンカーリンク部分
#date[1~31]([a~o])
(例)
http://neconote.jp/html5/table_scroll.html#date15h
--


P.S.5 サンプルでは、グループ名に高知県東部の自治体名、氏名には高知家の架空の面々を使用しました。15人目のO列は、15と丸にちなんでこの人しかいないと『淀屋満月』さんに登場してもらいました(^^)


P.S.6 早々のお褒めの言葉を頂きまして、ありがとうございます。大した技術ではありませんが、弊社のプログラムの売りは丁寧さと簡便さで、どなたにでも継続してご利用頂けるものと自負しております(若干の例外もありますが、ごめんなさい)。これからもよろしくお願いします。

P.S.6-2 前回もレスポンスが超早かったのですが、きっと四六時中、ガレコレHPをチェックしてもらっていますね。プログラミングはやらないけど、何となく分かった気になるのが楽しいらしい。トドロは、プログラミングに関してほぼ冬季限定労働者でしたが、今年度は年中頑張る予定です。ガレコレ信者さん、また儲けさせて下さいね。

P.S.7 文字絵は、iPhoneなど、文字をきちんと等幅で表示できないブラウザー環境では、レイアウトが崩れます。文字の配列を工夫して、何とか見れるようにしています。お許しを。
http://neconote.jp/html5/table_scroll.html
 
お問い合わせ
by Network Communication Note