スクロールでヌルっと出るメニュー

スクロールでヌルっと出るメニュー
Image by Hans Braxmeier from Pixabay

2021.05.18(更新日:2021.10.20)

結構頻度がある?かもしれないメニューの見せ方。
ワンカラムが多くなっている昨今、グローバルメニューを表示させるには使い勝手がいい。
久々にやったらまったく忘れていたので、jQueryなしでのコードだが残しておく。

この記事は1年以上経過しています。内容的に古い場合があります。

ヌルっと出てくる仕様

大抵ヘッダータグあたりにグローバルナビってものを置いてあると思うので、それを前提に今回コーディングする。
いろんなサイトを参考にしてみたが、最初から「header」部分を「position:fixed」してあるのが多かった。なら話は簡単なんだけど、それはしたくない。
なのでクローンを作り、それらをヌルっと出し入れすることにする。(コードはあちこち参考にして組み合わせているのことをご了承ください…)

HTMLコード

/* HTML */
<header>
  <nav>
    <h1>header</h1>
  </nav>
</header>

見本の中身は省略しているので適宜変更。ポイントは「header内」をボックスで一括「nav(divでもいい)」で囲むこと。

CSSコード

/* CSS */
header,
#header-clone {
	width: 100%;
	text-align: center;
	padding: 3em;
	background: #ccc;
	-webkit-box-sizing: border-box;
	box-sizing: border-box;
}
#header-clone {
	position: fixed;
	top: -100%;
	left: 0;
	z-index: 99;
	-webkit-transition: all 1s ease-out;
	transition: all 1s ease-out;
}
#header-clone.is-show {
	top: 0;
}

今回クローンした部分は「#header-clone」として設定。見た目はheaderと同じにしてあるので適宜変更。
クローン部分にclassを付与して出たり入ったりをさせる。

JSコード

/* javascript */
(function() {
	const header = document.querySelector( 'header' );
	const header_clone = document.createElement( 'div' );
	header_clone.setAttribute('id', 'header-clone' );
	const clone = header.firstElementChild.cloneNode(true);
	header_clone.appendChild( clone );
	document.body.appendChild( header_clone );
	
	const headerH = header.clientHeight;
	let scroll_position = 0;
	let ticking = false;

	window.addEventListener('scroll', function(e) {
		let scroll_position = window.scrollY;
		
		if (!ticking) {
			window.requestAnimationFrame(function() {
				doSomething( scroll_position );
				ticking = false;
			});

			ticking = true;
		}
	});

	function doSomething(scroll_pos) {
		if( scroll_pos > headerH * 3 ){
			header_clone.setAttribute( 'class', 'is-show' );
		} else if( scroll_pos < headerH * 4 ){
			header_clone.removeAttribute( 'class', 'is-show' );
		}
	}

})();

「requestAnimationFrame」の部分はMDNを参考にしてみた。
このJSを読み込んだ時点で、クローンを作成している。bodyの一番下に追加し、普段は見えない位置までCSSで調整しているので邪魔にはならないと思う。
見え隠れするスクロール値は「doSomething」の「headerH * n」の「n値」で調整。
元のheaderの高さの倍数で調整している。

カスタマイズ時の注意点

めちゃめちゃ単純に出来た訳だが、カスタマイズする時には以下に注意。

  • クローン部分はheaderの最初の直下の子要素
  • クローンするので、headerの子要素内はidセレクタを付与しないこと

後はよしなに。