■ カーソル位置のセルの上端と横端をハイライトする JavaScript
好評の、読み込ませるだけで動く JavaScript シリーズの5段目くらいです。このシリーズもたまってきたので、そのうちまとめます。
Excel とかの表計算ソフトって選択しているセルの列番号や行番号がハイライトされたりしてますよね?table タグ上であれと同じものを実現する JavaScript を書いてみました。
こんなようなテーブルを作らなくちゃいけない事になりそうなんだけど…。
| A | B | C | D | |
|---|---|---|---|---|
| 1 | ||||
| 2 | ||||
| 3 | ||||
| 4 |
実際には15×20くらいはあるので、チェックを入れる時にすごく使い辛そうですよね。なので、カーソルの位置がわかりやすくなるようにハイライト出来たら便利だろうと思ったんです。
rowspan とか colspan を使って複雑にしていると、上端とか横端の位置を取得するのがやたらと面倒になってくるので、画面上のセルの位置を元に計算してハイライトするセルを割り出しています。
はてなグラフ のデータ編集画面のように、rowspan や colspan が全く無いシンプルな構成だと、もっと単純なスクリプトで動作させる事が出来ます。Highlight Hatena Graph Table Header っていう Greasemonkey スクリプトを書いたので、良かったらこっちも見て下さい。
コードは以下の通りです。
function highlightTable(param) {
for(var p in param)
this[p] = param[p];
this.posRow = this._setRow();
this.posCell = this._setCell();
}
highlightTable.prototype.set = function() {
var table = this.table;
for(var i in table.rows) {
for(var f in table.rows[i].cells) {
var elm = table.rows[i].cells[f];
if(!elm.style) continue;
addEvent(elm, 'mouseover', this.coloring(i, f, this.color||'#EEEEAA'));
addEvent(elm, 'mouseout', this.coloring(i, f));
}
}
}
highlightTable.prototype.coloring = function(i, f, color) {
var elm = this.table.rows[i].cells[f];
var _this = this;
return function(e) {
var row = _this.getParentRow(i, f);
var cell = _this.getParentCell(i, f);
elm.style.backgroundColor = color||'';
row.style.backgroundColor = color||'';
cell.style.backgroundColor = color||'';
}
}
highlightTable.prototype.getParentRow = function(i, f) {
var pos = this._get(this.posRow, this.table.rows[i].cells[f].offsetTop);
return this.table.rows[pos].cells[0];
}
highlightTable.prototype.getParentCell = function(i, f) {
var pos = this._get(this.posCell, this.table.rows[i].cells[f].offsetLeft);
return this.table.rows[0].cells[pos];
}
highlightTable.prototype._get = function(pos, m) {
for(var z in pos) {
if(pos[z][1] < m + 5 && m < pos[z][2]) {
return pos[z][0];
}
}
return 0;
}
highlightTable.prototype._setRow = function() {
var table = this.table;
var pos = new Array;
var ret;
var x = 0;
for(var z in table.rows) {
if(!table.rows[z].cells) continue;
var cell = table.rows[z].cells[0];
if(ret-- && ret >= 1) continue;
ret = (cell.rowSpan-1);
pos[++x] = new Array;
pos[x][0] = z;
pos[x][1] = cell.offsetTop;
pos[x][2] = cell.offsetTop+cell.offsetHeight;
}
return pos;
}
highlightTable.prototype._setCell = function() {
var table = this.table;
var pos = new Array;
var x = 0;
for(var z in table.rows[0].cells) {
var cell = table.rows[0].cells[z];
if(!cell.colSpan) continue;
pos[++x] = new Array;
pos[x][0] = z;
pos[x][1] = cell.offsetLeft;
pos[x][2] = cell.offsetLeft+cell.offsetWidth;
}
return pos;
}
function addEvent(elm, type, event) {
if(elm.addEventListener) {
elm.addEventListener(type, event, false);
} else {
elm.attachEvent('on'+type, event);
}
}
ここまでの部分を外部ファイルとかで読み込ませておいて、
function init() {
var obj = new highlightTable({table: document.getElementById('hltable')});
obj.set();
}
addEvent(window, 'load', init);
なんて感じに呼び出してやると、hltable っていう ID がついてるテーブルに対してハイライトの設定を行ないます。
別の色でハイライトさせたい場合は、
new highlightTable({table: document.getElementById('hltable'), color: '#EEAAAA'});
って感じに color を指定するようにすれば良いです。
テーブルが複数ある場合は、その分 new をしてやれば簡単に対応出来ます。
その他、詳しくは動作サンプルの内容を見て下さい。
ちなみに coloring の中で、return する前に getParentRow とかをしても動くのですが、画面読み込み時の初期化に時間がかかるようになるため、今の形に落ち着いてます。
Posted by Kyosuke Takayama at 2006-02-21 (Tue) 23:59 printable version


○ 鷹の島: カーソル位置の…を CSS のみで実装 (2006-03-01 (Wed) 22:06) 0%