【jQuery】.hover()を高速移動するとアニメーションが蓄積されてよくわからないことになる問題を解決する

# .hover() 見切ったりとか思ってたら甘かった

前回投稿した記事 [【jQuery】.hover( )を使うときの、当たり前かもしれない構文](https://qiita.com/kape/items/b211ceb7a7e2aa9b1323#comment-385bb8aa0a38246abb8c) のこのjQuery。

<p data-height="265" data-theme-id="0" data-slug-hash="oMrvEY" data-default-tab="html,result" data-user="kapeking" data-pen-title="ドロップダウンメニュー" class="codepen">See the Pen <a href="https://codepen.io/kapeking/pen/oMrvEY/">ドロップダウンメニュー</a> by かぺ (<a href="https://codepen.io/kapeking">@kapeking</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

コメントにて指摘をいただきました。
高速でホバーを繰り返すと・・・あれ！？ホバーしてなくても動き続けているよ！？
この「いっこく堂現象」をどうにかすべく再び調べました。

```js:jQuery(いっこく堂現象発生時例)
$(".navTitle").hover(function(){
                $(this).children('ul').slideDown("fast");
            }, function() {
                $(this).children('ul').slideUp("fast");
            });
```


##２パターンの解決方法
2通りの解決方法をご紹介。
それぞれの結果は同じなので動作は同じだけど、意味が違うようなので（自分が）覚えやすいように紹介するよ！
参考記事 [not(“:animated”)とstop()の使い分けについて〜jQuery  |  IT工房｜Webデザイン入門](https://itstudio.co/2016/10/20/6300/)

### ① not(“:animated”)
アニメーション中ではないときにアニメーションの命令を受け付ける
＝アニメーション中はアニメーションの命令を受け付けない
＝**アニメーション中のhover「（アニメーションの命令に対して）だが断る。なぜなら私は忙しいから。」**
※最後のイコール文はイメージです。

<p data-height="265" data-theme-id="0" data-slug-hash="oPvgLd" data-default-tab="html,result" data-user="kapeking" data-pen-title="ドロップダウンメニュー（いっこく堂現象解消Ver）" class="codepen">See the Pen <a href="https://codepen.io/kapeking/pen/oPvgLd/">ドロップダウンメニュー（いっこく堂現象解消Ver）</a> by かぺ (<a href="https://codepen.io/kapeking">@kapeking</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

動作を確認してみてください。
ボタンの上を高速移動してもいっこく堂現象が起きない！

記述方法は以下

```js:jQuery①
$(".subList").hide();
$(".navTitle").hover(function(){
    $(this).children('ul:not(:animated)').slideDown("fast");
	},function(){
	$(this).children('ul:not(:animated)').slideUp("fast");
	});
```
参考記事 [jQueryでドロップダウンメニューを作る | JavaScript Archives（ジャバスクリプト アーカイブス）](http://www.takaya-com.jp/archives/2015/10/dropdownmenu/)
###② .stop()
stop関数といふものを使う方法。
stop関数は、アニメーション中のものを強制的に中断させる方法。なので、アニメーションの命令を再度出すと途中から始まります。
でも、このまま使うと最初のアニメーション自体もストップしちゃうので、**コールバック関数**というものを使います。

このコールバック関数というもの、私は「メインの処理が終わったらこの処理発動させてね～」程度の認識だったのですが
厳密には違う・・・？また調べなきゃ。。。

今回で言うとコールバック関数はここ。

```js:コールバック関数
$(this).children('ul').slideDown("fast",【コールバック関数】);
```
つまり、ここにstop関数を入れると「スライドダウンのアニメーションが終わったら後の命令はストップしてね！」となるわけです。
これでstop関数を使ったいっこく堂現象を解消する方法もできました！

<p data-height="265" data-theme-id="0" data-slug-hash="BOBqrp" data-default-tab="html,result" data-user="kapeking" data-pen-title="ドロップダウンメニュー【.stop()】" class="codepen">See the Pen <a href="https://codepen.io/kapeking/pen/BOBqrp/">ドロップダウンメニュー【.stop()】</a> by かぺ (<a href="https://codepen.io/kapeking">@kapeking</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

記述方法は以下

```js:jQuery② 
$(".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のアニメーションが連続で動作してしまった時に見る記事](https://www.marineroad.com/staff-blog/15861.html)
[stop() | jQuery日本語リファレンス](http://semooh.jp/jquery/api/effects/stop/_/)
[JavaScriptコールバックを整理してみた【再入門】](https://qiita.com/nekoneko-wanwan/items/f6979f687246ba089a35)

これでドロップダウンメニューは自分で作れるようになったぜ。ドゥフフフフ。

##最後に

実際に動かしてみて気づいたけど、紹介した二つの方法でも、動きが若干違うんだね・・・。
最初は単純に①のほうが記述が楽だから①のほうがいいなと思ってたけど
高速で動かしてみたら②のほうがぬるっと動いてる感があってステキ。
①は高速で動かしてもとりあえずアニメーションを最後まで遂行するので言うこと聞いてくれてる感が若干・・・。ううむ。
これは、設置するときのTPOを考えて決めるべきだと私は思いました。