上スクロールでふわっと降りてきて、下スクロールで消えるトップメニュー
を作ってみました。
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;
});
});