【jQuery】かんたん!ヘッダーナビを自動で非表示にするsetTimeout()とclearTimeout()

2014.8.30 JS / jQuery

かんたん!スクロールするとスライドインするナビを自動で非表示にするjQueryのsetTimeout()とclearTimeout()|ツーブロッカ satohmsys

スクロールすると画面上部にヒョコっと現れるメニューをjQueryで実装してみます!

CSSを調節すればスマートフォン用のwebサイトにも使えるので、キャンペーンページとかクーポンとかセールとか、強引な導線設計にもってこいなデザインです。

さらに、今回はユーザーに気を配って時間経過による非表示機能を実装しようと思います!

かんたん!スクロールするとスライドインするナビを自動で非表示にするjQueryのsetTimeout()とclearTimeout()

まずはHTMLを準備します。

HTML

CSS

メニューをjQueryで非表示にする前のHTMLだけのデモ

上部のメニュー.slidedownが、最初は隠れているけれどスクロールした量に応じて上から降りてくるイメージです。
画面にフィックスさせるために

  • position:fixed;
  • top:0;

この2点は必須で、幅は任意で調節してください。
ただ、このタイプのUIなら横幅いっぱいに領域が広がっていたほうが美しい気がします。。

わかりやすくするためにメニューを隠していませんが、実装を始めるにあたりdisplay:noneを書き足しましょう。

CSS

では、jQueryを書いていきます。

.on()で、スクロールしたときにメニューをスライドダウンさせるjQuery

もちろん、jQueryライブラリを読ませておいてください。

jQueryライブラリ

jQuery

//テスト用と書いてある行は、今回、特に動作に影響しません。

そこそこスクロールするとメニューが出てくるだけのデモ

4行目、6行目ぐらいの変数に注目してください。これらがメニューが出現するタイミングを設定する役目を果たしています。

変数contHeightbodyの高さを取得しています。
JavaScriptで画面サイズを取得する | かえラボBlog

そのbodyの高さを5で割った値$Limitです。コンテンツの1/5までスクロールしたらメニューが出るようにしています。

かんたん!スクロールするとスライドインするナビを自動で非表示にするjQueryのsetTimeout()とclearTimeout()

ここは5でなくても、3で割ってもいいです。割る値が大きければ大きいほど、数値が小さくなるので、のちにメニューが降りてくるポイントが早くなるということです。

次にこの辺りですが、ここでスクロール時に起こるイベントを設定しています。

$scrollValueはウィンドウ上部からのスクロール値を代入しています。
スクロールイベントの中に入れないと意味が無いので注意しましょう!
scrollTop() – jQuery 日本語リファレンス
1分でわかるjQueryのscrollTop() スクロール位置取得の使い方 | iwb.jp

そのスクロール値が、先ほどの$Limit(コンテンツ高さの1/5)よりも大きくなった時に、「slideMenu.slideDown(‘slow’)」処理が行われます。

ここでメニューを表示させています。ニュルッと。
速い方がいいという方は、(‘slow’)を(‘fast’)に変えてください。
slideDown([speed], [callback]) – jQuery 日本語リファレンス

slideUpとslideDownをifで振り分けてメニューの表示/非表示

先ほどのjQueryの記述だと、全体の1/5スクロールし終えた際にメニューが出っぱなしです。

これはだらしない!という方は、if(){~}に続けて、else{~}を記述します。

jQuery

これはif()の条件に当てはまらなかったときの処理ですので、今回の場合は、”全体の1/5よりもスクロール値が少ない場合”ということになります。

かんたん!スクロールするとスライドインするナビを自動で非表示にするjQueryのsetTimeout()とclearTimeout()

スクロール値は画面上部から、スクロールが始まる度に加減して数えているので、”全体の1/5よりもスクロール値が少ない場合”はslideUp()処理が行われます。
slideUp([speed], [callback]) – jQuery 日本語リファレンス

これにより、メニューが上へ引っ込みます。同時に、display:noneとなります。

そこそこスクロールするとメニューが出てきて、上にスクロールして戻るとメニューが引っ込んで非表示になるデモ

setTimeout()とclearTimeout()で、時間差で表示になるメニューにする

現在、ページの下にいるときにずっと上部にメニューが出ている状態です。
ページ全体の長さに対し1/5以内に収まってる時にのみ、メニューが隠れます。

せっかく下まで読んでくれているのにメニューがずっと降りているなんてだらしない!という方に、
次は、一定時間の経過でメニューが閉じるようにします。

スクリプトを書き換えます。(一部は変更なしです)

jQuery

win.on(‘scroll’ , function(){~})前後が変わっています。

まず、ポイントとしては、スクロールイベントの前に変数slideUpTimer = false;を定義しています。
スクロールイベント中は、変動しない変数は定義したくないですしね。

少し進んで、以下の箇所が更にポイントです。

変数slideUpTimerがfalseでないとき、つまり、値が入っているとき、clearTimeoutが実行されます。
JavaScriptリファレンス – clearTimeout:ITpro
これでslideUpTimerの処理をクリアしています。

そのすぐ後のifは先ほどと同じで、スクロールの量に応じメニューを出す処理です。

最後に、slideUpTimerに関数を代入しています。
setTimeoutという関数を使っています。これは、setTimeout内の処理を指定した時間だけ遅らせて実行する、という関数です。
一定時間で繰り返す(setTimeout)-JavaScript入門

slideMenuが、3秒後(3,000ミリ秒)にslideUpするという処理をslideUpTimerに入れておきます。

上記のコードに【1】~【3】まで番号が振ってありますが、この順に実行されるんですね。

  1. slideUpTimerが無効に
  2. スクロール値に応じメニュー出る
  3. 3秒後にメニュー引っ込む

で、この処理というのは.on(‘scroll’ , function(){~})内の記述であるため、ピクリとでもスクロールされた瞬間に【1】~【3】が実行されるのです。

かんたん!スクロールするとスライドインするナビを自動で非表示にするjQueryのsetTimeout()とclearTimeout()

つまり、マウスホイールを1ミリでも動かそうものなら【3】まで進んだ処理でslideUpTimerに何が入ろうと【1】のclearTimeout()にかき消されてしまうため、
【1】~【2】を行ったり来たりするわけなのです。

【3】の処理を行いたい、3秒後にメニューを閉じたい場合には、スクロールを止めるしか無いのです。

これが、3秒後にメニューが閉じる仕組みです!

そこそこスクロールするとメニューが出てきて、スクロールを止めて3秒後に自動でメニューが非表示になるデモ

ポイントとしては

  • タイマー用変数(例:slideUpTimer)は、scrollなどイベントでリアルタイムに行われる処理の外で定義すること
  • setTimeoutには、何秒後かに実行したい処理をかくこと

でし!

ちなみにこの箇所ですが

必要に応じてelse処理でメニューを引っ込ませて非表示にしてもいいのですが、なかなか慌ただしかったのでコメントアウトしています。

 

いかがでしょう?結構簡単ですよね。

しかも便利なUIだと思います。

使いどころに寄っては極端に鬱陶しく思われそうなので注意しましょう…

 

 

でわ!

Profile

東京でWebデザイナー・コーダーとして、フロントエンド的なことからデザイン思考的なことを考えたりして、ごにょごにょと活動中。(ポートフォリオ)Webクリエイターでは珍しい(?) HIPHOP, R&B好き。休日はよくカフェや漫画喫茶に出向いたりパン屋に行ったりコーヒ豆買いに行ったり、主に散歩しています。。デザインのトレンドやデザイン思考、HTML、CSSからSASS、Javascript、Wordpress構築などコーディングのTIPSなどをブログにアップしていきます。その他のことはtwitter( @satohmsys )まで。コーヒー友達募集中。