ここから本文です

CSS マウスホバーさせた時、親要素の背景を変えたい リスト(footer ul li a)に...

nan********さん

2015/6/2421:36:13

CSS マウスホバーさせた時、親要素の背景を変えたい

リスト(footer ul li a)にマウスホバー時、背景の色を変えたいのですが

リストから2つ上のfooterに背景色を変える書き方が分かりません。

画像でイメージするのが難しいのですが、紫色の矢印がマウスカーソルです。

footer ul li a,footer&gt,li&gt,myFooter&quot,マウスホバー,li onmouseover,ul&gt

閲覧数:
2,901
回答数:
1
お礼:
100枚

違反報告

ベストアンサーに選ばれた回答

ven********さん

2015/6/2506:14:05

おはやですヽ(^▽^*

CSS では、
包含される子孫要素のスタイルは指定できますが、
親要素をたどってスタイルを指定することはできません。

なので、
孫要素の <li> にマウスを乗せたときに、
親要素をたどって <footer> の背景を変えることはできません。

それをやるには、Javascript の力が必要です・ω・)b'


-*-*-*◆ しくみ ◆*-*-*-

Javascript を使うと言っても、しくみはごく簡単。
<li> にマウスを乗せて「mouseover」イベントが発生したら、
<footer> の背景を変える、
ただ、それだけです。

これを普通にやろうとすると、
▼────────
<footer>
<ul>
<li onmouseover="…">~</li>
<li onmouseover="…">~</li>
<li onmouseover="…">~</li>
<li onmouseover="…">~</li>

</ul>
</footer>
────────▲
のように、
<li> 要素ひとつひとつに対して
「onmouseover」を指定しないといけません。
でも、
<li> 要素ひとつひとつに指定するのは、
ちょっと面倒だし何となくスッキリ感がありませんね。

そこで、
<footer> の mouseover イベントに、
まとめて処理を仕込みます。
▼────────
<footer onmouseover="~">
<ul>
<li>~</li>
<li>~</li>
<li>~</li>
<li>~</li>

</ul>
</footer>
────────▲

まず、
<footer> のなかにある <li> 要素にマウスが乗ると、
<li> 要素で mouseove イベントが発生します。
<li> の「onmousemove」に何か処理を仕込んでおけば、
その処理が実行されます。

発生した mouseover イベントは、
<li> ⇒ <ul> ⇒ <footer> ⇒ …
というように、
親要素に次々にバブル伝搬していきます。
伝搬した先で「onmouseover」に処理が仕込んであれば、
そのたびに仕込んである処理が実行されます。

なので、
<footer> の「onmouseover」に処理を仕込んでおけば、
<footer> の中のどの <li> にマウスが乗っても、
処理を実行することができる、というワケですねヽ(・ω・*

<footer> の「onmouseover」に処理を仕込む処理のセットを、
関数として作成しておきましょう。
関数名は hoverFooter() とかでイイですね♪
関数には、
マウスイベントの情報を取得する引数 evt を用意しておきます。
▼────────
function hoverFooter( evt ){

}
────────▲

では、
関数 hoverFooter() の中身を作っていきましょう。

まずイベントが発生した要素(マウスが乗った要素)を
target として特定します。
▼────────
var target = evt.target || window.event.srcElement;
────────▲
そして、
マウスが乗った要素の種類が <li> だった場合は、
<footer> の背景を「赤」にし、
それ以外の場合は「透明」にしてみます。
書き方としては、
┌────────
| footer 要素の背景
| = ( target は <li> 要素 ) ? 赤 : 透明 ;
└────────
というふうに、
「3項演算子」の「?」をつかって条件分岐させると簡単です。
<footer> 要素に、
「id="myFooter"」のように id を付けておいた場合は、
▼────────
document.getElementById("myFooter").style.background
= ( target.TagName.match(/li/i) ) ? "red" : "transparent" ;
────────▲
のようになりますね♪

関数 hoverFooter() は以上で完成!
でも、
これだけだと、
マウスを降ろしても <footer> の背景が戻りません。
戻すためには、
マウスを降ろしたときに発生する「onmouseout」に、
色を戻す処理を仕込んでおかないといけません。

そこで、
<footer> の色を元に戻す関数 resetFooter() も用意しましょう。
▼────────
function resetFooter( evt ){
document.getElementById("myFooter").style.background
= "transparent";
}
────────▲
以上で resetFooter() も完成♪

あとは、
これらの関数を、
<footer> の onmouseover と onmouseout に
それぞれ仕込んでおくだけです゜▽^)b'
それぞれの関数の引数には、
イベントオブジェクト event を渡しておきましょう。
▼────────
<footer id="myFooter"
onmouseover="hoverFooter( event )"
onmouseout="resetFooter( event )"
>
<ul>
<li>~</li>
<li>~</li>
<li>~</li>
<li>~</li>

</ul>
</footer>
────────▲


-*-*-*◆ 実施例1 ◆*-*-*-

以上を踏まえて、
ソースコードの実施例を示します。

▼────────
<!--─ フッター ─-->
<footer id="myFooter"
onmouseover="hoverFooter( event )"
onmouseout="resetFooter( event )"
>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</footer>

<!--─ スクリプト ─-->
<script type="text/javascript">

/*----[ 関数:マウスを乗せたとき ]----*/

function hoverFooter( evt ){
var target = evt.target || window.event.srcElement;
myFooter.style.background =
( target.tagName.match(/li/i) ) ? "#f69" : "transparent";
}

/*----[ 関数:マウスを外したとき ]----*/

function resetFooter( evt ){
myFooter.style.background = "transparent";
}

</script>
────────▲


-*-*-*◆ 足りないもの ◆*-*-*-

<li> 要素の中に何も要素が入らない場合は、
上記の実施例で OK ですが、
<li> 要素の中に <a> 要素などを入れる場合、
上記の実施例だと、
<a> にマウスが乗ったときは、
<footer> の背景は透明(transparent)になってしまいます。
┌────────
| target は <li> 要素 ?
└────────
という条件分岐をしているからですね。

条件分岐を
┌────────
| target は <li> または <a> 要素 ?
└────────
というふうに変更すれば回避できますが、
もう少し確実な方法に変更しましょう。
┌────────
| target は <li> 要素の子孫 ?
└────────
という条件で処理を分岐させます。

target が <li> の子孫かどうかを調べるには、
<li> の親要素を順に辿って行って、
<footer> よりも先に <li> 要素に出くわせば、
target <li> 要素の子孫というコトになりますね。
▼────────
var target = evt.target || window.event.srcElement;
//--> 調査用のフラグ hit を用意
var hit = 0;
//------> target に親要素がある限り繰り返す
while( target.parentNode ){
//------> target が #myFooter なら終了
if( target.id == "myFooter" ){ break }
//------> target が <li> なら hit を 1 増やして終了
if( target.tagName.match(/li/i) ){
hit++;
break;
}
//------> target を親要素に変更
target = target.parentNode;
}
────────▲

これで変数 hit が 0 のままでなければ、
target は <li> 要素の子孫、というコトになります。


-*-*-*◆ 実施例2 ◆*-*-*-

上記の子孫判定を追加して、
実施例を修正したサンプルを示します。

▼────────
<!--─ フッター ─-->
<footer id="myFooter"
onmouseover="hoverFooter( event )"
onmouseout="resetFooter( event )"
>
<ul>
<li><a href="">A</a></li>
<li><a href="">B</a></li>
<li><a href="">C</a></li>
<li><a href="">D</a></li>
</ul>
</footer>

<!--─ スクリプト ─-->
<script type="text/javascript">

/*----[ 関数:マウスを乗せたとき ]----*/

function hoverFooter( evt ){
var target = evt.target || window.event.srcElement;
var hit = 0;
while( target.parentNode ){
if( target.id == "myFooter" ){ break }
if( target.tagName.match(/li/i) ){
hit++;
break;
}
target = target.parentNode;
}
myFooter.style.background = hit ? "#f69" : "transparent";
}

/*----[ 関数:マウスを外したとき ]----*/

function resetFooter( evt ){
myFooter.style.background = "transparent";
}

</script>
────────▲


-*-*-*◆ 実施例3 ◆*-*-*-

#myFooter のスタイルを直接変更せず、
クラス名を切り替えることで、
背景を切り替えることも出来ます。

▼────────
<!--─ スタイルシート(CSS) ─-->
<style type="text/css">
#myFooter{
background: transparent;
}
#myFooter.hover{
background: #f69;
}
</style>

<!--─ フッター ─-->
<footer id="myFooter"
onmouseover="hoverFooter( event )"
onmouseout="resetFooter( event )"
>
<ul>
<li><a href="">A</a></li>
<li><a href="">B</a></li>
<li><a href="">C</a></li>
<li><a href="">D</a></li>
</ul>
</footer>

<!--─ スクリプト ─-->
<script type="text/javascript">

/*----[ 関数:マウスを乗せたとき ]----*/

function hoverFooter( evt ){
var target = evt.target || window.event.srcElement;
var hit = 0;
while( target.parentNode ){
if( target.id == "myFooter" ){ break }
if( target.tagName.match(/li/i) ){
hit++;
break;
}
target = target.parentNode;
}
myFooter.className = hit ? "hover" : "";
}

/*----[ 関数:マウスを外したとき ]----*/

function resetFooter( evt ){
myFooter.className = "";
}

</script>
────────▲

質問した人からのコメント

2015/6/25 22:24:50

長文解説ありがとうございます。

html以外にphpしか触った事無くて、javascriptを使用せずにcssのみでアニメーションなどを導入しようかと考えていましたが流石に限界があるのですね。

現状javascriptの「j」も知らない状態ですが、helloworldから初めて理想の動作ができるwebサイトを完成させようと思います。

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる