Written by Toshiki

【脱jQuery】スクロールしたら画面上部に追従メニューを表示する方法

JavaScript Web制作

こんにちは、トシキです。
今回は以前に投稿した、「スクロールしたら画面上部に追従メニューを表示する方法(jQuery使用)」のJavaScriptバージョンを解説していきます。

本記事の内容

スポンサードサーチ

【脱jQuery】スクロールしたら画面上部に追従メニューを表示する方法

挙動はjQuery版と変わりません。
またコードに関してもHTML、CSSはそのままです。

See the Pen 【脱jQuery】スクロールしたら画面上部にスライド表示されるメニュー by tosshii (@totototosshii) on CodePen.

01. HTML




<header class="ly_header">
  <nav class="bl_headerNav" aria-hidden="false" aria-label="ヘッダーメニュー">
    <ul class="bl_header_list">
      <li><a href="#1">ヘッダーメニュー01</a></li>
      <li><a href="#2">ヘッダーメニュー02</a></li>
      <li><a href="#3">ヘッダーメニュー03</a></li>
      <li><a href="#4">ヘッダーメニュー04</a></li>
    </ul>
  </nav>
  <nav class="ly_fixedNav" aria-hidden="true" aria-label="追従メニュー">
    <ul class="bl_fixedNav_list">
      <li><a href="#5">追従メニュー01</a></li>
      <li><a href="#6">追従メニュー02</a></li>
      <li><a href="#7">追従メニュー03</a></li>
      <li><a href="#8">追従メニュー04</a></li>
    </ul>
  </nav>
</header>

<section class="ly_cont">
  <h2>メインコンテンツ</h2>
</section>

変更なしです。

02. CSS




/* SCSS
ヘッダー部分 */
.ly_header {
  padding: 30px;
  background-color: #ddd;
}

.ly_fixedNav {
  position: fixed;
  top: -100%;
  left: 0;
  width: 100%;
  padding: 30px;
  background-color: #b6e1b5;
  transition: top .8s, visibility .8s;
  visibility: hidden;
}

.bl_header_list,
.bl_fixedNav_list {
  display: grid;
  column-gap: 1em;
  grid-auto-columns: 1fr;
  grid-auto-flow: column;
  max-inline-size: max-content;
  margin-inline: auto;
  li {
    display: grid;
    place-items: center;
  }
  a {
    line-height: 1.5;
    padding: 1em;
  }
}
/* ヘッダー部分ここまで */

/* メインコンテンツ */
.ly_cont {
  height: 2000px;
  background-color: lightblue;
  text-align: center;
  padding: 30px 0;
}

こちらも変更なしです。

03. JavaScript



// 追従メニューの関数
const FixedNav = () => {
  const scroll = window.pageYOffset;
  const header = document.querySelector('.bl_headerNav');
  const fixed = document.querySelector('.ly_fixedNav');
  const isHeaderVisible = header.offsetHeight >= scroll - 60;
  header.style.visibility = isHeaderVisible ? 'visible' : 'hidden';
  header.setAttribute('aria-hidden', !isHeaderVisible);
  fixed.style.top = isHeaderVisible ? '-100%' : '0';
  fixed.style.visibility = isHeaderVisible ? 'hidden' : 'visible';
  fixed.setAttribute('aria-hidden', isHeaderVisible);
};

// 画面をスクロールをしたら発火
window.addEventListener('scroll', () => {
  FixedNav();
})

window.pageYOffsetで現在のスクロール位置を取得します。



const isHeaderVisible = header.offsetHeight >= scroll - 60;

header.offsetHeight.bl_headerNavの要素の高さを取得し、scroll - 60は現在のスクロール位置から60px引いた値になります。
スクロール位置が60px未満の場合はtrue、それ以上ならfalseisHeaderVisibleに代入されます。



header.style.visibility = isHeaderVisible ? 'visible' : 'hidden';
fixed.style.top = isHeaderVisible ? '-100%' : '0';
fixed.style.visibility = isHeaderVisible ? 'hidden' : 'visible';

.styleでCSSのプロパティ(visibilitytop)の値を書き換えています。
入る値は三項演算子で条件分岐しています。



header.setAttribute('aria-hidden', !isHeaderVisible);
fixed.setAttribute('aria-hidden', isHeaderVisible);

.setAttributearia-hidden属性の値を書き換えています。
isHeaderVisibleにはtruefalseが代入されているので、そのいずれかの値がaria-hidden属性に入ります。
!isHeaderVisible!は否定演算子で、isHeaderVisibletrueならばfalse、逆にfalseならばtrue!isHeaderVisibleに入ります。

04. まとめ

今回はJavaScriptバージョンを解説しました。
jQueryより記述量は増えますが、やっていることは変わらず、ヘッダーメニューと追従メニューの情報を取得→スクロール位置によってCSSとaria-hiddenに変更を加える処理になります。
記述の順番もjQueryバージョンと変わらないので、脱jQueryを目指している人は見比べてみるといいかと思います。

人気記事Webサイトにフォントサイズ変更ボタンを実装する方法(jQuery使用)

人気記事【脱jQuery】スクロールしたら画面上部に追従メニューを表示する方法