【JavaScript】スクロールしたらついてくるナビの作り方
【JavaScript】スクロールしたらついてくるナビの作り方
以前にも、自身のブログでjQuery版は記載しましたが、今回はJavaScriptでやる方法です。
jQueryと内容的にはやっていることに変わりはありません。
最近ではjQueryを使わないで欲しいという要望も多くなってきました。
JavaScriptで書く場合、様々な方法があるとは思いますがメモがてらこちらに記載しておきます。
誰かのお役に立てば幸いです。
HTML
<header class="header" role="banner"> <h1 class="header-logo"><a href="">大見出し</a></h1> <nav class="nav"> <ul class="nav-list"> <li><a href="">メニュー</a></li> <li><a href="">メニュー</a></li> <li><a href="">メニュー</a></li> </ul> </nav> </header> <main class="main"> <!-- メインコンテンツ部分 --> </main> <footer class="footer" role="contentinfo"> <small class="copyright">©2020 ておりこ</small> </footer>
CSS
.fixed { width: 100%; position: fixed; top: 0; left: 0; z-index: 1; /* 必要に応じて */ }
JavaScript
window.onscroll = function () { let gHeader = document.getElementsByClassName('header')[0]; //headerを任意のclass名に let gNav = document.getElementsByClassName('nav')[0]; // navを任意のclass名に let gNavHeight = gNav.clientHeight; let gMain = document.getElementsByClassName('main')[0]; // mainを任意のclass名に if (window.pageYOffset >= gHeader.clientHeight) { gNav.classList.add('fixed'); // fixedを任意のclass名に gMain.setAttribute('style', 'padding-top:' + gNavHeight + 'px'); } else { gNav.classList.remove('fixed'); // fixedを任意のclass名に(上記と同じにする) gMain.setAttribute('style', 'padding-top:0;'); //padding-top:0;を任意の数値に } }
解説
window.onscroll = function() でスクロールをした時に動作するようにします。
今回は getElementsByClassName でclass名にてそれぞれの要素を指定します。
getElementsByClassNameの場合、[0]という風に配列の添字をつけてあげないと正しく取得できませんので注意してください。
*今回はこのclass名は1度しかHTML上に存在しないという前提ですので、添字が[0]となっています。場合によっては[0]ではないこともあるのでそこも注意が必要です。
スクロールしていき、ナビゲーション部分がブラウザの一番上に来た時(正確にはスクロール量がナビゲーションの位置まで来た時)にclass名を付与します。
jQueryではaddClass()メソッドですが、JavaScriptの場合はclassList.add()を使用して、class名を付与します。
fixedというclassにはposition:fixedなどのCSSを記載しておきます。
そうすることでナビゲーションがブラウザの上についてくるようになります。(いわゆる、スティッキーヘッダーというやつです)
それに加えて、
.setAttribute(‘style’,’padding-top:’+ gNavHeight + ‘px’);
という処理を行います。
これはjQueryだとattrメソッドにあたります。
style属性のpadding-topを付与します。
ナビゲーションがfixedすることでナビゲーション分の高さがなくなるので、この処理をしておかなければガタつきが出ます。
最後に、スクロール量がナビゲーション位置よりも少ない場合は classList.remove() を使用しclass名を外すようにします。
setAttribute(‘style’, ‘padding-top:0;’);
でpadding-topも0に戻しておきます。(ここはもしご自身でpaddingを設定している場合はその数値にしてください。)
さいごに
classList.add() も classList.remove() もclass名を引数にします。
ここで指定する場合は、文字列として(ダブルクォーテーションかシングルクォーテーションで囲む)引数を指定しないと変数として扱われてエラーとなるので注意してください。