質問: CSS マウスホバーさせた時、親要素の背景を変えたい リスト(footer ul li a)にマウスホバー時、背景の色を変えたいのですが
回答: おはやですヽ(^▽^* CSS では、 包含される子孫要素のスタイルは指定できますが、 親要素をたどってスタイルを指定することはできません。 なので、 孫要素の にマウスを乗せたときに、 親要素をたどって の背景を変えることはできません。 それをやるには、Javascript の力が必要です・ω・)b' -*-*-*◆ しくみ ◆*-*-*- Javascript を使うと言っても、しくみはごく簡単。 にマウスを乗せて「mouseover」イベントが発生したら、 の背景を変える、 ただ、それだけです。 これを普通にやろうとすると、 ▼──────── ~ ~ ~ ~ ... ────────▲ のように、 要素ひとつひとつに対して 「onmouseover」を指定しないといけません。 でも、 要素ひとつひとつに指定するのは、 ちょっと面倒だし何となくスッキリ感がありませんね。 そこで、 の mouseover イベントに、 まとめて処理を仕込みます。 ▼──────── ~ ~ ~ ~ ... ────────▲ まず、 のなかにある 要素にマウスが乗ると、 要素で mouseove イベントが発生します。 の「onmousemove」に何か処理を仕込んでおけば、 その処理が実行されます。 発生した mouseover イベントは、 ⇒ ⇒ ⇒ ... というように、 親要素に次々にバブル伝搬していきます。 伝搬した先で「onmouseover」に処理が仕込んであれば、 そのたびに仕込んである処理が実行されます。 なので、 の「onmouseover」に処理を仕込んでおけば、 の中のどの にマウスが乗っても、 処理を実行することができる、というワケですねヽ(・ω・* の「onmouseover」に処理を仕込む処理のセットを、 関数として作成しておきましょう。 関数名は hoverFooter() とかでイイですね♪ 関数には、 マウスイベントの情報を取得する引数 evt を用意しておきます。 ▼──────── function hoverFooter( evt ){ ~ } ────────▲ では、 関数 hoverFooter() の中身を作っていきましょう。 まずイベントが発生した要素(マウスが乗った要素)を target として特定します。 ▼──────── var target = evt.target || window.event.srcElement; ────────▲ そして、 マウスが乗った要素の種類が だった場合は、 の背景を「赤」にし、 それ以外の場合は「透明」にしてみます。 書き方としては、 ┌──────── | footer 要素の背景 | = ( target は 要素 ) ? 赤 : 透明 ; └──────── というふうに、 「3項演算子」の「?」をつかって条件分岐させると簡単です。 要素に、 「id="myFooter"」のように id を付けておいた場合は、 ▼──────── document.getElementById("myFooter").style.background = ( target.TagName.match(/li/i) ) ? "red" : "transparent" ; ────────▲ のようになりますね♪ 関数 hoverFooter() は以上で完成! でも、 これだけだと、 マウスを降ろしても の背景が戻りません。 戻すためには、 マウスを降ろしたときに発生する「onmouseout」に、 色を戻す処理を仕込んでおかないといけません。 そこで、 の色を元に戻す関数 resetFooter() も用意しましょう。 ▼──────── function resetFooter( evt ){ document.getElementById("myFooter").style.background = "transparent"; } ────────▲ 以上で resetFooter() も完成♪ あとは、 これらの関数を、 の onmouseover と onmouseout に それぞれ仕込んでおくだけです ゚▽^)b' それぞれの関数の引数には、 イベントオブジェクト event を渡しておきましょう。 ▼──────── ~ ~ ~ ~ ... ────────▲ -*-*-*◆ 実施例1 ◆*-*-*- 以上を踏まえて、 ソースコードの実施例を示します。 ▼──────── A B C D ────────▲ -*-*-*◆ 足りないもの ◆*-*-*- 要素の中に何も要素が入らない場合は、 上記の実施例で OK ですが、 要素の中に 要素などを入れる場合、 上記の実施例だと、 にマウスが乗ったときは、 の背景は透明(transparent)になってしまいます。 ┌──────── | target は 要素 ? └──────── という条件分岐をしているからですね。 条件分岐を ┌──────── | target は または 要素 ? └──────── というふうに変更すれば回避できますが、 もう少し確実な方法に変更しましょう。 ┌──────── | target は 要素の子孫 ? └──────── という条件で処理を分岐させます。 target が の子孫かどうかを調べるには、 の親要素を順に辿って行って、 よりも先に 要素に出くわせば、 target 要素の子孫というコトになりますね。 ▼──────── var target = evt.target || window.event.srcElement; //--> 調査用のフラグ hit を用意 var hit = 0; //------> target に親要素がある限り繰り返す while( target.parentNode ){ //------> target が #myFooter なら終了 if( target.id == "myFooter" ){ break } //------> target が なら hit を 1 増やして終了 if( target.tagName.match(/li/i) ){ hit++; break; } //------> target を親要素に変更 target = target.parentNode; } ────────▲ これで変数 hit が 0 のままでなければ、 target は 要素の子孫、というコトになります。 -*-*-*◆ 実施例2 ◆*-*-*- 上記の子孫判定を追加して、 実施例を修正したサンプルを示します。 ▼──────── A B C D ────────▲ -*-*-*◆ 実施例3 ◆*-*-*- #myFooter のスタイルを直接変更せず、 クラス名を切り替えることで、 背景を切り替えることも出来ます。 ▼──────── A B C D ────────▲