ソート [2006-07-05-2] に引続き,
行数の多い表の場合,ヘッダ部がスクロールアウトしてしまわないように固 定したくなる.
というようなニーズもやっぱり結構あって,実際いろんなところでそういう 機能を実現する JavaScript のコードが公開されている.いくつか当たって みた中で,一番気に入ったのはこれ:
気に入った理由は,
って要するに崩れないことが重要.他の方の実装も含めて,要するにヘッダ 部と本体とを分離して別の table 要素にして,本体だけにスクロールバー をつける,というのが動作原理なので,列幅の再現性をいかに高くするかが ポイントになる,のだと思う.ここで紹介されているコードは,(やっぱり ちょっとはズレる場合があるのだけど) かなりイケている,と思う.ありが たく使わせて頂いております.
テーブルの height は px 単位で指定するようになっている.画面全体に対 するパーセンテージで指定できると便利かな,と思って
newDiv2.style.height = tHeight+'px';
のところを 'px' じゃなくて '%' にしてみたのだけど,doctype スイッチ [2005-11-15-2] に引っかかるようになってしまった.doctype 宣言にシス テム識別子がある場合,'px' だとスクロールバーが出るけど '%' だと出 ない.システム識別子がなければ,どちらでもスクロールバーが出る.謎.
作者の Mars さんも書いておられますが,このままだと印刷するときちょっ と困る (全体が印刷できない).というわけで,かなりアドホックですが, こんな回避策をとってます.
(以下の実装は obsolete → メモその3 へ)
まずグローバルな変数を 2 個用意.
var newDiv2; var myHeight;
Tscroller() の中で newDiv2 をローカル変数として宣言するのをやめて, このグローバル変数を使うことにする.つまり単に
var newDiv2 = document.createElement('div');
を
newDiv2 = document.createElement('div');
にする.それから Tscroller() の中のどこかで
myHeight = tHeight;
してやる.最後に
function ToggleScroll()
{
if (newDiv2.style.height == '') {
newDiv2.style.height = myHeight + 'px';
} else {
newDiv2.style.height = '';
}
}
な関数を定義しておいて,適当な場所から href なり onclick なりで呼べ るようにしておく.これでスクロールバーをオン・オフできます.たぶん.
もっときれいに作れる気もするけど,最小の改造でやるならこんなところだ ろうか.
メモその2 がちょっとあまりにもアドホックすぎた気がする.テーブル 2 つ以上扱おうとしたらもうダメだし.もうちょっとだけ真面目に書きます.
メモその2 で書いた改造はすべて撤廃,改めて元の Tscroller() の最後あ たりに以下を入れて,
newDiv2.height_saved = tHeight;
以下のような関数を定義する.
function ToggleScroll(tid)
{
var newDiv2 = document.getElementById('D_' + tid + '_B');
var tHeight = newDiv2.height_saved;
if (newDiv2.style.height == '') {
newDiv2.style.height = tHeight + 'px';
} else {
newDiv2.style.height = '';
}
}
引数には Tscroller に与えたのと同じく,テーブルの id を渡します.
<a href="javascript:ToggleScroll('tb')">
Click here to toggle the scroller</a>.
div に height_saved なんていうプロパティを勝手に作っているところが非 常にうさんくさい.こういうことするのって規格上はダメなんですかね? 一 応 IE と Firefox では動いている模様.
HTML の表を,列名をクリックしてソートできるようにしたい.
というようなニーズは結構あって,実際いろんなところでそういう機能を実 現する JavaScript のコードが公開されている.いくつか当たってみた中で, 一番気に入ったのはこれ (の試作5):
気に入った理由は,
という辺り.ありがたく使わせて頂いております.
実際の表は,<td> の中にテキストが直接書かれているとは限らなく,たと えば <a> で囲まれたテキストが書かれてたりとかすることもあるわけで, 一般にはテキストに行き着くまで DOM ツリーを再帰的にたどってやる必要 がある.データ取得関数 getfn が分離されているので,こんなコードを書 いて getfn として渡してやることにした.
function byStrNoCase (cell) {
return extractText(cell).toLowerCase();
}
function byInt (cell) {
return parseInt(extractText(cell));
}
function extractText(node) {
var text = '';
if (node.nodeType == 3) { // TEXT_NODE
text = node.nodeValue;
} else if (node.hasChildNodes()) {
var n = node.childNodes.length;
for (var i = 0; i < n; i++) {
text = text + extractText(node.childNodes[i]);
}
}
return text;
}
JavaScript の Array の sort() は,安定であるとは保証されていないらし い.実際,IE は安定なソートをしてくれているっぽいが Firefox だと安定 でない.テーブルをかちかちクリックしてソートしたいときというのは,た とえば計算機一覧を,まずホスト名順にソートして,それから管理者順にソー トしてから,自分が管理者になってる子たちを見る,なんていう使い方をす ることが多いので,ソートは安定であって欲しい.
一番安直にやるには,ソート対象の要素にプロパティとして元の順番も持た せておいて,比較して引き分けだったら元の順番を保存するような比較関数 cmpfn を渡してやればよい.
のだが,元のコードだと,getfn が返した値を Object 型に変換してそれを ソートしているので,比較の結果として引き分けにならない.しかたないの で,getfn の返した値を Object 型に変換するのではなく,Object のプロ パティとして getfn の返した値を持たせてやるように書き換えて使ってい る.つまり
for(var i=0; i<N; i++)
x[i] = Object( getfn( rows[i].cells[index] ) ), x[i].row=rows[i];
の部分を
for(var i=0; i<N; i++) {
x[i] = new Object;
x[i].v = getfn(rows[i].cells[index]);
x[i].row = rows[i];
x[i].idx = i;
}
にしてやる.cmpfn は
function cmpAsc(a, b) {
if (a.v == b.v) {
if (a.idx == b.idx) {
return 0; // can't happen
} else if (a.idx > b.idx) {
return 1;
} else {
return -1;
}
} else if (a.v > b.v) {
return 1;
} else {
return -1;
}
}
function cmpDesc(a, b) {
return cmpAsc(b, a);
}
みたいな感じ.
2008 : 01 02 03 04 05 06 07 08 09 10 11 12
2007 : 01 02 03 04 05 06 07 08 09 10 11 12
2006 : 01 02 03 04 05 06 07 08 09 10 11 12
2005 : 01 02 03 04 05 06 07 08 09 10 11 12
2004 : 01 02 03 04 05 06 07 08 09 10 11 12
2003 : 01 02 03 04 05 06 07 08 09 10 11 12
2002 : 01 02 03 04 05 06 07 08 09 10 11 12
2001 : 01 02 03 04 05 06 07 08 09 10 11 12
2000 : 01 02 03 04 05 06 07 08 09 10 11 12
1999 : 01 02 03 04 05 06 07 08 09 10 11 12
1998 : 01 02 03 04 05 06 07 08 09 10 11 12
1997 : 01 02 03 04 05 06 07 08 09 10 11 12
1996 : 01 02 03 04 05 06 07 08 09 10 11 12
最終更新時間: 2008-04-23 08:31