.hover() 見切ったりとか思ってたら甘かった
前回投稿した記事 【jQuery】.hover( )を使うときの、当たり前かもしれない構文 のこのjQuery。
See the Pen ドロップダウンメニュー by かぺ (@kapeking) on CodePen.
コメントにて指摘をいただきました。
高速でホバーを繰り返すと・・・あれ!?ホバーしてなくても動き続けているよ!?
この「いっこく堂現象」をどうにかすべく再び調べました。
$(".navTitle").hover(function(){
$(this).children('ul').slideDown("fast");
}, function() {
$(this).children('ul').slideUp("fast");
});
2パターンの解決方法
2通りの解決方法をご紹介。
それぞれの結果は同じなので動作は同じだけど、意味が違うようなので(自分が)覚えやすいように紹介するよ!
参考記事 not(“:animated”)とstop()の使い分けについて〜jQuery | IT工房|Webデザイン入門
① not(“:animated”)
アニメーション中ではないときにアニメーションの命令を受け付ける
=アニメーション中はアニメーションの命令を受け付けない
=アニメーション中のhover「(アニメーションの命令に対して)だが断る。なぜなら私は忙しいから。」
※最後のイコール文はイメージです。
See the Pen ドロップダウンメニュー(いっこく堂現象解消Ver) by かぺ (@kapeking) on CodePen.
動作を確認してみてください。
ボタンの上を高速移動してもいっこく堂現象が起きない!
記述方法は以下
$(".subList").hide();
$(".navTitle").hover(function(){
$(this).children('ul:not(:animated)').slideDown("fast");
},function(){
$(this).children('ul:not(:animated)').slideUp("fast");
});
参考記事 jQueryでドロップダウンメニューを作る | JavaScript Archives(ジャバスクリプト アーカイブス)
② .stop()
stop関数といふものを使う方法。
stop関数は、アニメーション中のものを強制的に中断させる方法。なので、アニメーションの命令を再度出すと途中から始まります。
でも、このまま使うと最初のアニメーション自体もストップしちゃうので、コールバック関数というものを使います。
このコールバック関数というもの、私は「メインの処理が終わったらこの処理発動させてね~」程度の認識だったのですが
厳密には違う・・・?また調べなきゃ。。。
今回で言うとコールバック関数はここ。
$(this).children('ul').slideDown("fast",【コールバック関数】);
つまり、ここにstop関数を入れると「スライドダウンのアニメーションが終わったら後の命令はストップしてね!」となるわけです。
これでstop関数を使ったいっこく堂現象を解消する方法もできました!
See the Pen ドロップダウンメニュー【.stop()】 by かぺ (@kapeking) on CodePen.
記述方法は以下
$(".subList").hide();
$(".navTitle").hover(function(){
$(this).children('ul').slideDown("fast",function(e){$(".subList").stop(false, true);});
},function(){
$(this).children('ul').slideUp("fast",function(e){$(".subList").stop(false, true);});
});
参考記事
【jQuery】hoverのアニメーションが連続で動作してしまった時に見る記事
stop() | jQuery日本語リファレンス
JavaScriptコールバックを整理してみた【再入門】
これでドロップダウンメニューは自分で作れるようになったぜ。ドゥフフフフ。
最後に
実際に動かしてみて気づいたけど、紹介した二つの方法でも、動きが若干違うんだね・・・。
最初は単純に①のほうが記述が楽だから①のほうがいいなと思ってたけど
高速で動かしてみたら②のほうがぬるっと動いてる感があってステキ。
①は高速で動かしてもとりあえずアニメーションを最後まで遂行するので言うこと聞いてくれてる感が若干・・・。ううむ。
これは、設置するときのTPOを考えて決めるべきだと私は思いました。