今日ちょっとつまったので調べながら解決した。
まずこちらをの記事をご覧あれ。
「jQueryで作る多階層ドロップダウンメニュー」
http://ascii.jp/elem/000/000/475/475908/
cssまわりは、はしょります。
jquery部分の記述を見ると、こうなっている
ここはわかりやすい。
<ul class="sub">を初期値で隠しておくということ。
jQueryではよくあるやり方っすね。
次に2行目からの構造の部分
.hover()については、元記事でも説明しているけど、
マウスが乗ったときには「ホニャララ」を実行して、マウスが降りたときには「プギャー」を実行するという構文。
「ドットホバー命令カンマ命令」と口にだして覚えておこう。
実際のもので説明すると、
<ul class="menu">の子要素である<li>にマウスが乗ったときに「ホニャララ」が実行されて、<li>からマウスが外れると「プギャー」が実行される。
さて、次が一番の難関。ホニャララに相当する部分。
ここには、3つくらいの要素がぎゅっとつまっている。
一番シンプルな部分を抜き出すと
という部分が見えてくる。
これは、あらかじめdisplay:hiddenなどで見えなくしていた<ul>を出現させる、
速いスピードでスライドの動きをさせながら出現させる。
という意味だよね。
slideDown("fast")とかはとくに気にする必要はなくて、
とにかく、隠れてた<ul>というタグを出現させる、ということ。その”スライドさせる”、とか”速く”とか、エフェクト部分はおまけみたいなもんだ。 そしてこの基本の出現の処理に、ひとつの追加命令を入れる。
"ul"の次にカンマthisが入った。
thisというのはjQueryの命令文の中で発動条件となったcssが入ってくる。
今回の事例で言うと、↓この部分
じゃぁこの"ul",thisというのがどういう意味かというと、調べたところ
「thisの子要素であるul」という意味らしい。
thisは「ul.menu li」のことであったから、
書き換えると
と同じ意味になる。
言葉で説明すると、
という意味になりますよ。
そしてあの難しい1文に入っていた3つめの要素が
の部分。
これがなくても動くは動く。でもどんな問題が起きるかというと、
マウスを載せたり降ろしたりを素早く繰り返してみると、その回数繰り返したぶんだけ、表示したり非表示になったりが後を追うようになんどもなんどもくり返してしまう。
ちょっと言葉じゃわかりにくいので、not(:animated)をはずして試してみるといい。
not(:animated)を入れると、同じようにマウスをのせたり降ろしたりを繰り返しても、処理は繰り返されない。
not(:animated)とは、
「アニメーションしてる最中のものに対しては、ホニャララを実行しないよ」
という意味になる。
なので、動いてる最中のものにマウスを乗せても、命令は実行しません。
動くのがとまってから実行しますよ、と。
だから、処理は1度しか行われずに、すっきりする。
これで、一番難しい部分の
が理解できる。
ここで最後の疑問。
<li>にマウスを乗せたら、その子要素の<ul>が表示されるのはわかったYO。
でも、その<ul>にマウスを移動させても開き続けているのはなぜ?
これは、まぁ、<li>の子要素である<ul>に移動しても、まだ<li>にマウスが乗っているのと同じ意味だから。
というシンプルな回答になってしまうんだけど、元記事で注意としてさらりと書かれているのは、
mouseover()とmouseout() を併用して、今回のhover()と同じことをやろうとしてもうまくいかないよ、ということ。
hover()の場合は、子要素に移動しても新たに処理はスタートしないから、ずっとマウスオーバーしている状態とみなされる。
<li>からその子要素である<ul>にマウスを移動しても、<li>に乗ったままなので、ひらきっぱなしですよー、という状態になる。
一方、mouserover()とmouseout()併用の場合は、子要素に移動したときに、新たな処理の始まりだと認識する。
だから、<li>にマウスオーバーして子要素の<ul>が開いた後、その<ul>にマウスを移動させると、<ul>が一度パッと消えて、もう一度開くような動きをしてしまう。slideDownが再度始まっちゃうってことだね。
なので、ドロップダウンメニューを作るときは.hover()でつくろうね、という結論であった。
まずこちらをの記事をご覧あれ。
「jQueryで作る多階層ドロップダウンメニュー」
http://ascii.jp/elem/000/000/475/475908/
cssまわりは、はしょります。
jquery部分の記述を見ると、こうなっている
$(function(){$("ul.sub").hide();$("ul.menu li").hover(function(){$("ul:not(:animated)",this).slideDown("fast")},function(){$("ul",this).slideUp("fast");})})
jqueryの基礎を一応勉強した僕ですが、これでなぜうまくいくのかいまいちわからなかったので
調べながら理解したので説明。
まず1行目。
まず1行目。
$("ul.sub").hide();
ここはわかりやすい。
<ul class="sub">を初期値で隠しておくということ。
jQueryではよくあるやり方っすね。
次に2行目からの構造の部分
$("ul.menu li").hover(function(){ホニャララ},function(){プギャー})
.hover()については、元記事でも説明しているけど、
マウスが乗ったときには「ホニャララ」を実行して、マウスが降りたときには「プギャー」を実行するという構文。
「ドットホバー命令カンマ命令」と口にだして覚えておこう。
実際のもので説明すると、
<ul class="menu">の子要素である<li>にマウスが乗ったときに「ホニャララ」が実行されて、<li>からマウスが外れると「プギャー」が実行される。
さて、次が一番の難関。ホニャララに相当する部分。
$("ul:not(:animated)",this).slideDown("fast")
ここには、3つくらいの要素がぎゅっとつまっている。
一番シンプルな部分を抜き出すと
$("ul").slideDown("fast")
という部分が見えてくる。
これは、あらかじめdisplay:hiddenなどで見えなくしていた<ul>を出現させる、
速いスピードでスライドの動きをさせながら出現させる。
という意味だよね。
slideDown("fast")とかはとくに気にする必要はなくて、
とにかく、隠れてた<ul>というタグを出現させる、ということ。その”スライドさせる”、とか”速く”とか、エフェクト部分はおまけみたいなもんだ。
$("ul",this).slideDown("fast")
"ul"の次にカンマthisが入った。
thisというのはjQueryの命令文の中で発動条件となったcssが入ってくる。
今回の事例で言うと、↓この部分
$(function(){$("ul.sub").hide();$("ul.menu li").hover(function(){$("ul:not(:animated)",this).slideDown("fast")},function(){$("ul",this).slideUp("fast");})})
じゃぁこの"ul",thisというのがどういう意味かというと、調べたところ
「thisの子要素であるul」という意味らしい。
thisは「ul.menu li」のことであったから、
書き換えると
$("ul.menu li ul").sildeDown("fast")
と同じ意味になる。
言葉で説明すると、
<ul class="menu">の子要素の<li>にマウスを乗せると、さらにその<li>の子要素の<ul>が速いスピードでスライドしながら出現する>
という意味になりますよ。
そしてあの難しい1文に入っていた3つめの要素が
not(:animated)
の部分。
これがなくても動くは動く。でもどんな問題が起きるかというと、
マウスを載せたり降ろしたりを素早く繰り返してみると、その回数繰り返したぶんだけ、表示したり非表示になったりが後を追うようになんどもなんどもくり返してしまう。
ちょっと言葉じゃわかりにくいので、not(:animated)をはずして試してみるといい。
not(:animated)を入れると、同じようにマウスをのせたり降ろしたりを繰り返しても、処理は繰り返されない。
not(:animated)とは、
「アニメーションしてる最中のものに対しては、ホニャララを実行しないよ」
という意味になる。
なので、動いてる最中のものにマウスを乗せても、命令は実行しません。
動くのがとまってから実行しますよ、と。
だから、処理は1度しか行われずに、すっきりする。
これで、一番難しい部分の
$("ul:not(:animated)",this).slideDown("fast")
が理解できる。
ここで最後の疑問。
<li>にマウスを乗せたら、その子要素の<ul>が表示されるのはわかったYO。
でも、その<ul>にマウスを移動させても開き続けているのはなぜ?
これは、まぁ、<li>の子要素である<ul>に移動しても、まだ<li>にマウスが乗っているのと同じ意味だから。
というシンプルな回答になってしまうんだけど、元記事で注意としてさらりと書かれているのは、
mouseover()とmouseout() を併用して、今回のhover()と同じことをやろうとしてもうまくいかないよ、ということ。
hover()の場合は、子要素に移動しても新たに処理はスタートしないから、ずっとマウスオーバーしている状態とみなされる。
<li>からその子要素である<ul>にマウスを移動しても、<li>に乗ったままなので、ひらきっぱなしですよー、という状態になる。
一方、mouserover()とmouseout()併用の場合は、子要素に移動したときに、新たな処理の始まりだと認識する。
だから、<li>にマウスオーバーして子要素の<ul>が開いた後、その<ul>にマウスを移動させると、<ul>が一度パッと消えて、もう一度開くような動きをしてしまう。slideDownが再度始まっちゃうってことだね。
なので、ドロップダウンメニューを作るときは.hover()でつくろうね、という結論であった。