要素を一定の時間マウスオーバー(ホバー)したら処理を走らせたい話

JavaScriptの話

2017.03.19

グローバルナビゲーションにドロップダウンリストをつけてマウスオーバーしたらピロンと現れる、という機能をCSSでつけたみました。が、あまりに反応が瞬時すぎて次のようなことに困ってしまいました。

  • ちょっとでもマウスが乗るとリストが現れてしまうので、見た目がちらちらする。割とうざったい。
  • ちょとでもマウスが外れるとリストが消えてしまうのでストレスになる。

もっとユーザー大雑把に操作させてくれてもいいじゃない!ということで、大雑把な操作に耐えられるよう、jQueryを書いてみました。

やりたいこと

該当要素の出現について

○秒ホバー(マウスオーバー)し続けたら処理を走らせる。○秒経つ前にホバーが外れたら何もしない。今回はCSSで「:hover」と記述していたところをクラス名「hover」に置き換えたいので該当の要素に「addClass(‘hover’)」をかけてあげます。

該当要素の撤去について

○秒マウスアウトし続けたら処理を走らせる。○秒経つ前にもともとマウスオーバーされていた要素に再びマウスオーバーされたら、何もしない。今回は先ほどつけられたクラス名を外したいので「removeClass(‘hover’)」をかけてあげます。

結論コード

結論としてはこんなコードになりました。
デモはこちら

鬼みたいに長いんですけどHTML

CSS

jQuery

jQuery自体の読み込みは割愛します。

正解は「clearTimeout()」。「delay()」「setTimeout()」は遅れるだけ。

「処理 遅らせる」などど検索すると「delay()」「setTimeout()」などが出てきますが、これだけだと処理を始めるまでの時間が遅れるだけで実際に処理はされます。250ミリ秒遅らせたとして、ちょろっとマウスが通過すると250ミリ秒遅れてリストがちょろっと出てすぐ消える、という具合なのでこれではなんだか奇妙です。

前述の結論コードの中でポイントになるのは「clearTimeout()」の部分です。「setTimeout()」と一緒に使い、「setTimeout()」のタイマーを解除します。

これを利用して要素の出現についてだけ記述するとこんな感じです。

第一階層メニューにマウスが乗ったら250ミリ秒遅れてそこにぶら下がる第二階層メニューが現れる。この一連の動きに「hoge」というキーネームを付けておきます。マウスが乗ってから250ミリ秒経つ前にマウスが外れたら「clearTimeout()」が働き、キーネーム「hoge」の起爆までのタイマーを解除します。

要素の撤去についてはこの逆を行います。すると結論コードのようになります。
かくしてめでたく意図した通りのドロップダウンリストが作れましたとさ。よかったね!

この記事へのコメント

コメントはまだありません。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

JavaScriptの話の最新記事

ページの先頭へ戻る