【クライアントのわがままに応える! 】
マウスオーバーで行や列をハイライト表示にしたい!
ストライプテーブルは、背景色を変更することでテーブルを見やすくする工夫の1つです。では、行や列の数が多いテーブルの場合、クライアントから「交互に色を変えるだけじゃなくて、マウスカーソルのある行と列を目立たせるようにして」と言われたら、どうしたらいいでしょうか。
マウス操作に応じて行や列をハイライト表示するには、マウスカーソルがテーブルのtd要素上に重なったタイミングで、td要素に対応する行と列の背景色を変更します。
■行のハイライト
まず、行をハイライトする部分から作ります。行のハイライト表示は、CSS3セレクターを使えば以下のように簡単です。
▼サンプル05(CSS部分)
tr:not(:first-child):hover{
background:#B2D8FF;
}
ただ、CSS3セレクターを使うとIEでは機能しないので、先ほど作ったストライプテーブルをベースに、jQueryで実装します。セレクターは tr:not(:first-child) で1行目(見出し行)以外のtr要素を指定し、マウスが重なったときのイベントをmouseover()とmouseout()で設定します(関連記事)。tr要素にマウスが重なると「hover」というclassを追加し、マウスが要素から外れると追加したclassを取り除きます。
▼サンプル06(スクリプト部分)
$("tr:not(:first-child)").mouseover(function(){
$(this).addClass("hover");
}).mouseout(function(){
$(this).removeClass("hover");
})
ハイライト時に変更する背景色はCSS側で設定します。今回は薄い青色(#B2D8FF)を設定しています。
.hover{
background:#B2D8FF;
}
■列のハイライト
行をハイライトする処理ができたら、今度は列の処理を作りましょう。列を一発でまとめて選択できるセレクターはないので、行に比べると手間はかかりますが、jQueryでは以下の手順で実装できます。
▼サンプル07(スクリプト部分)
$("td").mouseover(function(){
$("td:nth-child("+($("td").index(this)%$("th").size()+1)+")").addClass("hover");
}).mouseout(function(){
$("td:nth-child("+($("td").index(this)%$("th").size()+1)+")").removeClass("hover");
})
このサンプルでは、td要素にマウスが重なると、同じ列のtd要素に対して「hover」というclassを追加し、マウスが要素から離れるとhoverを削除するようになっています。セレクターの ($("td").index(this)%$("th").size()+1) の部分には見慣れない記述があり、何やらちょっと難しそうです。コードをいくつかに分割して少しずつ見ていきましょう。
$("td").index(this)
index(...)は、括弧内に記述した要素の順番(インデックス番号)を調べる命令です。上の場合は「this」、つまり現在マウスが重なっているtd要素が、 $("td") の中で何番目なのかを取得しています。JavaScriptでは数字を0から数えるので、最初の要素は「0」になります。今回のテーブルのtd要素は、以下のようなインデックス番号となっています。
no | Name | Birthday | Phone | |
---|---|---|---|---|
0 | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 |
30 | 31 | 32 | 33 | 34 |
35 | 36 | 37 | 38 | 39 |
$("th").size()
size()は、セレクターで指定した要素が存在する数を調べる命令です。今回はthを指定しているので、テーブルの列の数、つまり「5」を取得しています。
$("td").index(this)%$("th").size()
%(パーセント)は割り算の余りを求める記号(演算子)で、A%B と書くとAをBで割った余りを出します。上の場合は「マウスが重なっている要素のインデックス番号」を「th要素の数」で割っているので、1行目1列目にマウスがある場合は「0÷5」の余りの「0」を、2行目4列目の場合は「8÷5」の余りの「3」を取得できます。それぞれのセルにマウスが重なったときに得られる値をまとめると、以下のようになります。
no | Name | Birthday | Phone | |
---|---|---|---|---|
0 | 1 | 2 | 3 | 4 |
0 | 1 | 2 | 3 | 4 |
0 | 1 | 2 | 3 | 4 |
0 | 1 | 2 | 3 | 4 |
0 | 1 | 2 | 3 | 4 |
0 | 1 | 2 | 3 | 4 |
0 | 1 | 2 | 3 | 4 |
0 | 1 | 2 | 3 | 4 |
$("td").index(this)%$("th").size()+1
先ほど計算した「余り」の値に1を足します。すると、マウスカーソルが現在重なっている列の番号になります。列の番号を取得できたらあともう一歩です。nth-child()擬似クラス(関連記事)でtd要素を絞り込みます。
$("td:nth-child("+($("td").index(this)%$("th").size()+1)+")")
nth-child()は括弧内に要素の番号を指定するので、テキストの連結(関連記事)を利用して、ここまでの処理を括弧内に入れ込みます。これで、マウスが重なっているtd要素と同じ列をセレクターで選択し、classを追加したり、削除したりできるようになりました。
ここまでに作成したストライプテーブルの処理、行/列のハイライト処理をまとめて完成したのが以下のスクリプトです。
▼サンプル07(スクリプト部分)
$(function(){
$("th:nth-child(odd)").addClass("odd");
$("tr:nth-child(even)").addClass("even");
$("tr:not(:first-child)").mouseover(function(){
$(this).addClass("hover");
}).mouseout(function(){
$(this).removeClass("hover");
})
$("td").mouseover(function(){
$("td:nth-child("+($("td").index(this)%$("th").size()+1)+")").addClass("hover");
}).mouseout(function(){
$("td:nth-child("+($("td").index(this)%$("th").size()+1)+")").removeClass("hover");
})
})
【JavaScriptワンポイントレッスン 】
テキストの結合と計算式の違い
サンプル07では、以前に学習したテキスト(文字列)の結合が再登場しました。
$("td:nth-child("+($("td").index(this)%$("th").size()+1)+")")
上のソースコードと次のコードはどこが違うのか、見て分かるでしょうか?
$("td:nth-child("+$("td").index(this)%$("th").size()+1+")")
正解は $("td").index(this)%$("th").size()+1 を括弧で囲っているか、いないかの違いです。最初のコードでは、括弧内の+(プラス)は数値の計算式に使われていて、左右の値を足した値を返します。一方、2番目のコードは、括弧がないため、文字列の連結として扱われます。つまり、見た目は同じ「1+1」でも、前者の結果は「2」、後者は「11」となる、というわけです。
+(プラス)を利用する際には、計算式なのか文字列の連結なのか、書き方に注意しましょう。
著者:西畑一馬(にしはた かずま)
to-R代表、Webクリエイター。PHPによるシステム開発や、CMSを利用したWebサイト制作、SEO対策などのマーケティング、コンサルティング、Webクリエイター向けの講座などを業務で行なっている。また、ブログto-RではJavaScriptやSEO対策、CSS、Movable TypeなどのWeb制作にかかわるさまざまな情報を発信している。
主な著書に「現場のプロから学ぶXHTML+CSS」(共著、毎日コミュニケーションズ刊)がある。
ソーシャルリアクション
この連載の記事
一覧へWebPro
jQueryとAjaxで作るスムーズページング
WebデザイナーのためのjQuery入門。jQueryのAjax機能を使ってスムーズなページングを実現する方法をチュートリアルで解説する。