LoginSignup
0
1

More than 3 years have passed since last update.

途中から「fixed」で、上スクロールでふわっと降りてきて、下スクロールで消えるトップメニュー

Last updated at Posted at 2020-11-20

上スクロールでふわっと降りてきて、下スクロールで消えるトップメニュー

を作ってみました。

See the Pen Topmenu that appear-scrollup & hide-scrolldown by sarap422 (@sarap422) on CodePen.

よくあるやり方と若干違うのは、
最初から position: fixed; でなく、
スクロール量に応じて、途中から position: fixed; にしています。

つまり、どういうことかと言いますと、
スマホのときに、最初のトップメニューはそのまま使いたい
途中から、上スクロールで下タブ表示されるようにしたい
という動きになります。

あと最初が position: static;(初期値) のままだから、
レイアウト調整が楽とかもあるかもしれないですね。

解説部分

scroll量計算・グローバル変数

javascript

$(function () {
// グローバル変数
previous_scrY = 0;

// window 'scroll' があったとき
$(window).on("scroll", function () {
// scroll量計算
let current_scrY = window.pageYOffset;
let diff_scrY = current_scrY - previous_scrY;

current_scrY(現在スクロール量) - previous_scrY(前回スクロール量) で、上スクロールか下スクロールかと判定します。
「var」や「let」だと上手く行かなかったのですが、「グローバル変数」というのがあるらしいですね。これだと上手くいきました。

「position:fixed」に変更、「.hide」クラスで一旦隠す

javascript

// 現scrollY > 150 (※「pos:fixed」に変更、「.hide」で一旦隠す)
if (current_scrY > 150) {
    // 現scrollYが、前scrollYより大きい場合
    if (diff_scrY > 0) {
        // id '#' に、class'rolldown-hide'を追加
        $("#Meltlilith").removeClass("rollup-PC rollup-Mbl");
        $("#Meltlilith").addClass("rolldown-hide-PC rolldown-hide-Mbl");
    }
    // 現scrollYが、前scrollYより小さい場合
    if (diff_scrY < 0) {
        // id '#' に、class'rollup-hide'を追加
        $("#Meltlilith").removeClass("rolldown-PC rolldown-Mbl");
        $("#Meltlilith").addClass("rollup-hide-PC rollup-hide-Mbl");
    }

css

@media only screen and (max-width: 500px) {
.rollup-Mbl .toplogo, .rollup-Mbl .toplogo {
    display: none;
}
.rolldown-Mbl, .rolldown-hide-Mbl {
    position: fixed;
    z-index: 999;
    width: 100%;
    justify-content: center;
    bottom: -100%;
}

途中で、position: fixed; に変更する場合
cssの transition でふわっとならずに、すぐにドンと表示されたんですね。

それとスマホのときの、「最初は上表示 → 途中は下から表示」も上手く行かなかったので、一旦隠す処理を入れました。

隠していた「fixed」メニューを表示

javascript

// 現scrollY > 200
if (current_scrY > 200) {
    // 現scrollYが、前scrollYより大きい場合
    if (diff_scrY > 0) {
        // id '#' を、class'rolldown-hide' → 'rolldown'に移行
        $("#Meltlilith").removeClass("rolldown-hide-PC rolldown-hide-Mbl");
        $("#Meltlilith").addClass("rolldown-PC rolldown-Mbl");
    }
    // 現scrollYが、前scrollYより小さい場合
    if (diff_scrY < 0) {
        // id '#' を、class'rollup-hide' → 'rollup'に移行
        $("#Meltlilith").removeClass("rollup-hide-PC rollup-hide-Mbl");
        $("#Meltlilith").addClass("rollup-PC rollup-Mbl");
    }
} /*ƒ /if (current_scrY > 200) */

css

.rollup-Mbl {
    position: fixed;
    z-index: 999;
    width: 100%;
    justify-content: center;
    bottom: 0;
}

あとは「.roll-hide」クラスを削除して、「.roll」で表示というだいたい同じような作りですね。

最後に「現在のスクロール量」を次回スクロール時の比較値として記録

javascript

} else {
    /* not(current_scrY > 150) */
    // "roll"classを全削除
    $("#Meltlilith").removeClass(
        "rolldown-hide-PC rollup-PC rolldown-hide-PC rolldown-PC rolldown-hide-Mbl rollup-Mbl rolldown-hide-Mbl rolldown-Mbl"
    );
}

// 処理後に、現scrollYを、前scrollYとして記録
previous_scrY = current_scrY;

上に来たときは、 position: static;(初期値) に戻るよう「.roll」クラスを全削除、
処理が終わった最後に、現在のスクロール量を、次回比較値として記録します。

下タブ時はアイコンも表示されるようにしてみる

css

.rollup-Mbl [id^='Top__li'] i:before {
    font-family: 'Font Awesome 5 Free';
    font-weight: 900;
    font-style: normal;
    font-size: 1.5rem;
    /* content内での改行ありにする */
    white-space: pre;
}
.rollup-Mbl #Top__li-Home i:before {
    content: '\f015\a';
}
.rollup-Mbl #Top__li-Works i:before {
    content: '\f0b1\a';
}
.rollup-Mbl #Top__li-About i:before {
    content: '\f007\a';
}

疑似要素で、下タブ時はアイコンも表示されるようにもしてみました。
white-space: pre;content: '\a'; でアイコン改行です。

まとめ

ちなみにふわっと降りてくるだけなら、もう少しシンプルに。
既存のトップメニューのままでも、id付け加えるだけでもある程度は動くんじゃないでしょうか? 以上です。

css

/* scrollPeraFix-falling.js
  (上スクロールでTopbar表示、下スクロールで消去)
=================================================================== */

#Meltlilith {
    width: 100%;
    transition: all 0.3s ease-in-out;
}

.rolldown, .rollup-hide {
    position: fixed;
    z-index: 999;
    width: 100%;
    top: 0;
}

.rollup {
    position: fixed;
    z-index: 999;
    width: 100%;
    top: -100%;
}

javascript

/* scrollPeraFix-falling.js
  (上スクロールでTopbar表示、下スクロールで消去)
=================================================================== */

$(function () {
  // グローバル変数
  previous_scrY = 0;

  // window 'scroll' があったとき
  $(window).on("scroll", function () {
    // scroll量計算
    let current_scrY = window.pageYOffset;
    let diff_scrY = current_scrY - previous_scrY;

    // 現scrollY > 150 (※「pos:fixed」に変更、「.hide」で一旦隠す)
    if (current_scrY > 150) {
      // 現scrollYが、前scrollYより大きい場合
      if (diff_scrY > 0) {
        // id '#' に、class'rolldown-hide'を追加
        $("#Meltlilith").removeClass("rollup");
        $("#Meltlilith").addClass("rolldown-hide");
      }
      // 現scrollYが、前scrollYより小さい場合
      if (diff_scrY < 0) {
        // id '#' に、class'rollup-hide'を追加
        $("#Meltlilith").removeClass("rolldown");
        $("#Meltlilith").addClass("rollup-hide");
      }

      // 現scrollY > 200
      if (current_scrY > 200) {
        // 現scrollYが、前scrollYより大きい場合
        if (diff_scrY > 0) {
          // id '#' を、class'rolldown-hide' → 'rolldown'に移行
          $("#Meltlilith").removeClass("rolldown-hide");
          $("#Meltlilith").addClass("rolldown");
        }
        // 現scrollYが、前scrollYより小さい場合
        if (diff_scrY < 0) {
          // id '#' を、class'rollup-hide' → 'rollup'に移行
          $("#Meltlilith").removeClass("rollup-hide");
          $("#Meltlilith").addClass("rollup");
        }
      } /*ƒ /if (current_scrY > 200) */
    } else {
      /* not(current_scrY > 150) */
      // "roll"classを全削除
      $("#Meltlilith").removeClass(
        "rollup-hide rollup rolldown-hide rolldown"
      );
    }

    // 処理後に、現scrollYを、前scrollYとして記録
    previous_scrY = current_scrY;
  });
});
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1