jQuery:tableでマウスのhoverしている行と列の色を同時に変える方法(テーブルを少し美しく見せる方法)
先日より多用しているtableだったりするのですが、
実は一番やりたかったのが、この行と列の同時選択。
hoverしている行の色を変えるのは、先日のエントリー
「hoverで背景色が変わった後、交互に背景がついているところの色を元に戻す方法」
で紹介したばかりですが、それに列(縦)の色も変える方法が、
数日考えてもなかなかうまいこと動作してくれなかった。
今回は失敗内容を含めて書いておこうと思う。
列ってどうやって選択するんだ?
そもそも今回の内容を考える時に一番悩んだのが列の選択方法。
頭では「こんな風にやればできるなー」ってのがいくつか浮かんでいたけど、
どれもスクリプトでどうかけばいいのかわからなかった。
まず浮かんだのが下のスクリプト。
$('#test1 tr').each(function(){ var bgColor = $(this).css('backgroundColor'); var color = $(this).css('color'); $(this).hover(function(){ $(this).css({ backgroundColor:'#ff47a3', color:'#ffffff' }); },function(){ $(this).css({ backgroundColor:bgColor, color:color }); }); }); $('#test1 tr td').each(function(){ var bgColor = $(this).css('backgroundColor'); var color = $(this).css('color'); var hoge1 = $('#test1 tr').length-1; var hoge2 = $('#test1 tr').children().index(this) - 7; var hoge3 = hoge2%hoge1; if(hoge3 == 0){hoge3 = 8}; $(this).hover(function(){ $('#test1 tr td:nth-child('+hoge3+')').css({ backgroundColor:'#ff47a3', color:'#ffffff' }); },function(){ $('#test1 tr td:nth-child('+hoge3+')').css({ backgroundColor:bgColor, color:'#333333' }); }); });
hoverした位置をindex()で求めて、列の数で割って、
その余りが同じ列を選択するというもの。
ソースをみてもわかるように、長くて複雑…
そして何より、ちょっとしたバグを含んでいる。
見てみるのが一番なので、上のスクリプトを動作させてみる。
HTMLは先日と同じテーブルを使います。一番上の行はthの中身です。
■プレビュー
TH1 | TH2 | TH3 | TH4 | TH5 | TH6 | TH7 | TH8 |
---|---|---|---|---|---|---|---|
1−1 | 1−2 | 1−3 | 1−4 | 1−5 | 1−6 | 1−7 | 1−8 |
2−1 | 2−2 | 2−3 | 2−4 | 2−5 | 2−6 | 2−7 | 2−8 |
3−1 | 3−2 | 3−3 | 3−4 | 3−5 | 3−6 | 3−7 | 3−8 |
4−1 | 4−2 | 4−3 | 4−4 | 4−5 | 4−6 | 4−7 | 4−8 |
5−1 | 5−2 | 5−3 | 5−4 | 5−5 | 5−6 | 5−7 | 5−8 |
6−1 | 6−2 | 6−3 | 6−4 | 6−5 | 6−6 | 6−7 | 6−8 |
7−1 | 7−2 | 7−3 | 7−4 | 7−5 | 7−6 | 7−7 | 7−8 |
8−1 | 8−2 | 8−3 | 8−4 | 8−5 | 8−6 | 8−7 | 8−8 |
上手く行と列が選択できているのですが、問題はマウスを動かしたとき。
同じ行内を移動すると、なんと選択していたところの文字が変化してしまう。
同じ行内にいるときは、変化しないで欲しいのに…
と、それだけじゃなくて、一度変化するとそのままの色が引き継がれてしまう。
なんとか解決する方法はないのだろうか・・・
同じ列にclassをつけてみる
これも、先日書いたエントリーに
「jQueryを使い要素の出てくる順に番号をつける方法(forの代わりにeach()を使う繰り返し)」
で書いたように、同じ列にclassをつけることが可能である。
ということでclassをつけてそのclassに適応してみた
$("#test2 tr").each(function () { $(this).children().not('th').each(function (i) { i = i+1; $(this).addClass("item" + i); }); }); $('#test2 tr').each(function(){ var bgColor = $(this).css('backgroundColor'); $(this).hover(function(){ $(this).children().not('th').css({ backgroundColor:'#ff47a3', color:'#ffffff' }); },function(){ $(this).children().not('th').css({ backgroundColor:bgColor, color:'#333333' }); }); }); $('#test2 tr td').each(function(){ var bgColor = $(this).css('backgroundColor'); var selector = '.'+ $(this).attr('class'); $(this).hover(function(){ $(selector).css({ backgroundColor:'#ff47a3', color:'#ffffff' }); },function(){ $(selector).css({ backgroundColor:bgColor, color:'#333333' }); }); });
相変わらずソース長い…
もっとシンプルにできないものかな…なんて考えたけど、考えている余裕はなく、
これもさっきと同じ問題を含んでいた。
問題解決のために
要は同じ行内で、前後のtdにマウスを動かしたときに、
さっきまでいたところのtdの色が変わってしまうのが問題だった。
つまり、それさえ解決すれば同じ行内でマウスを動かしても色が変わらなくなる!
というわけで、先ほどのスクリプトに前後への移動時処理追加。
途中までは先ほどと同じなので、スクリプト省略します。
$('#test2 tr td').each(function(){ var bgColor = $(this).css('backgroundColor'); var selector = '.'+ $(this).attr('class'); $(this).hover(function(){ $(selector).css({ backgroundColor:'#ff47a3', color:'#ffffff' }); $(this).next().css({ backgroundColor:'#ff47a3', color:'#ffffff' }); $(this).prev().css({ backgroundColor:'#ff47a3', color:'#ffffff' }); },function(){ $(selector).css({ backgroundColor:bgColor, color:'#333333' }); }); });
単純にhoverしたところの前後の色も変化させるだけのもの。
これだけでなんとかうまく問題なく動作してくれるようになった。
しかし…スクリプト長いね。。。
ちょっとだけでもスクリプト省略するために
今回各部分の.cssで指定している部分って同じだよなー
なんておもったので、最初に機能として用意してみた。
$.fn.color = function(){ return this.each(function(){ $(this).css({ backgroundColor:'#ff47a3', color:'#ffffff' }); }); };
これを書いておくことで、いままで繰り返し指定していた部分を
.color()だけで指定できるようになった。
ということで完成
まだまだスクリプト長い気がしますが、とりあえず完成ってことで。
■スクリプト
$("#test2 tr").each(function () { $(this).children().not('th').each(function (i) { i = i+1; $(this).addClass("item" + i); }); }); $.fn.color = function(){ return this.each(function(){ $(this).css({ backgroundColor:'#ff47a3', color:'#ffffff' }); }); }; /*行の指定*/ $('#test2 tr').each(function(){ var bgColor = $(this).css('backgroundColor'); $(this).hover(function(){ $(this).children().not('th').color(); },function(){ $(this).children().not('th').css({ backgroundColor:bgColor, color:'#333333' }); }); }); /*列の指定*/ $('#test2 tr td').each(function(){ var bgColor = $(this).css('backgroundColor'); var selector = '.'+ $(this).attr('class'); $(this).hover(function(){ $(selector).color(); $(this).next().color(); $(this).prev().color(); },function(){ $(selector).css({ backgroundColor:bgColor, color:'#333333' }); }); });
■プレビュー
TH1 | TH2 | TH3 | TH4 | TH5 | TH6 | TH7 | TH8 |
---|---|---|---|---|---|---|---|
1−1 | 1−2 | 1−3 | 1−4 | 1−5 | 1−6 | 1−7 | 1−8 |
2−1 | 2−2 | 2−3 | 2−4 | 2−5 | 2−6 | 2−7 | 2−8 |
3−1 | 3−2 | 3−3 | 3−4 | 3−5 | 3−6 | 3−7 | 3−8 |
4−1 | 4−2 | 4−3 | 4−4 | 4−5 | 4−6 | 4−7 | 4−8 |
5−1 | 5−2 | 5−3 | 5−4 | 5−5 | 5−6 | 5−7 | 5−8 |
6−1 | 6−2 | 6−3 | 6−4 | 6−5 | 6−6 | 6−7 | 6−8 |
7−1 | 7−2 | 7−3 | 7−4 | 7−5 | 7−6 | 7−7 | 7−8 |
8−1 | 8−2 | 8−3 | 8−4 | 8−5 | 8−6 | 8−7 | 8−8 |
ここまでたどりつくのに3日もかかってしまった〜
やはり、発想力は必要ですね。
IE6でプレビューを見ると、onmouseoutした所の背景色がおかしくなっていく。
ぐりぐりマウスを動かしていると背景色が全部ブルーになったよ。
なんでだろうね
ありがとうございました。
行はJavaScriptを使わずにCSSのtr:hoverで色を変えて、列はJavaScriptで色を変えています。
http://ok2nd.me/abook/pc/list-hyakusen-sum.php