2006-02-21 (Tue)

カーソル位置のセルの上端と横端をハイライトする 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

この記事へのコメント

コメントはお気軽にどうぞ

Cookie に保存しますか?


・スパム対策のため、http:// を含むコメントの投稿は出来ません。
・スパムチェックのため、投稿がすぐに反映されない場合があります。
・メールアドレス入力欄には何も入力しないでください。

トラックバック

トラックバックURL: http://espion.just-size.jp/mt-tb.cgi/551

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

先日書いた カーソル位置のセルの上端と横端をハイライトする JavaScript を CSS のみで実装しちゃった方が居ました。 マウスカーソル位置のセルの左端のみをハイライトするCSS 残念ながら IE では対応していない等いくつか制限があるようですが、CSS だけでやろうと思う...


鷹の島: JavaScript ミニライブラリ (2006-07-17 (Mon) 18:30) 0%

ちょっと前から「なくても不便じゃないけど、あったらちょっと便利かもね」っていう JavaScript を書いたりして発表していましたが、一覧とか作ってないからどんなのがあるのかわかりにくかったのでまとめてみました。 onsubmit で disable 以外のスクリプトは全てパブリ...



この記事のリンク元

 
Copyright (C) Kyosuke Takayama, All rights reserved.