JavaScript

【jQuery】追従ナビゲーションのカレント表示

JavaScript

【jQuery】追従ナビゲーションのカレント表示

サイドバーの追従ナビゲーションに、現在地を示すためのカレント表示の方法をご紹介します。

サンプルをご覧ください

上記のサンプルを下にスクロールしてご確認ください。
メインコンテンツまでスクロールするとサイドバーが追従して、現在地を示すためのナビゲーションが表示されます。
今回はこちらの実装方法についてご説明します。

HTMLの記述

<!-- ヘッダー -->
<header>Header</header>
<div class="container">
  <!-- メインコンテンツ -->
  <main class="js-location-content">
    <section id="section01">
      <h2>Section 01</h2>
    </section>
    <section id="section02">
      <h2>Section 02</h2>
    </section>
    <section id="section03">
      <h2>Section 03</h2>
    </section>
  </main>
  <!-- サイドバー -->
  <aside class="js-location-nav">
    <ul>
      <li><a href="#section01" class="is-current">Section 01</a></li>
      <li><a href="#section02">Section 02</a></li>
      <li><a href="#section03">Section 03</a></li>
    </ul>
  </aside>
</div>
<!-- フッター -->
<footer>Footer</footer>

メインコンテンツとナビゲーションを紐つけるために、ID属性でアンカーリンクを設定しています。
ナビゲーションの最初の項目には「is-current」クラスを付けてます。

CSSの記述

/* スムーススクロールの指定 */
html{
  scroll-behavior: smooth;
}
header,footer{
  font-size: 20px;
  color: #fff;
  background: #000;
  text-align: center;
  padding: 60px;
  text-transform: uppercase;
}
.container{
  display: flex;
  justify-content: space-between;
  gap: 60px;
  max-width: 1000px;
  padding: 60px;
  margin: auto;
}
main{
  flex: 1;
}
section{
  height: 1000px;
  padding: 60px;
}
#section01{
  background: aquamarine;
}
#section02{
  background: coral;
}
#section03{
  background: blueviolet;
}
h2{
  font-size: 20px;
  text-transform: uppercase;
}
aside{
  width: 200px;
}
/* 追従の指定 */
ul{
  position: sticky;
  top: 0;
}
li{
  border-bottom: 1px solid #000;
}
a{
  display: block;
  color: #000;
  text-transform: uppercase;
  text-decoration: none;
  padding: 20px;
}
/* カレント表示の指定 */
.is-current{
  color: #fff;
  background: #000;
}

重要なポイントだけ紹介します。

  • スムーススクロールはhtmlタグに「scroll-behavior: smooth;」を指定します
  • サイドバーの追従は「position: sticky;」で指定します
  • ナビゲーションはカレント表示用のクラス「is-current」でプロパティを指定します

jQueryの記述

$(window).on('load scroll resize',() => {
  const nav = $('.js-location-nav'),
        //ナビゲーションの位置を取得
        navPosition = nav.offset().top,
        //現在のスクロール位置を取得
        scroll = $(window).scrollTop();
  
  //ナビゲーションの位置までスクロールしたか判定
  if(scroll >= navPosition){
    const content = $('.js-location-content section');
    
    //コンテンツごとに繰り返し処理
    content.each(function(i,e){
      //コンテンツの開始位置を取得
      const target = $(this).offset().top,
            //コンテンツの終了位置を取得
            targetPosition = target + $(this).innerHeight(),
            //コンテンツのID属性を取得
            id = $(e).attr('id');
      
      //該当するコンテンツまでスクロールしているか判定 && 該当するコンテンツを通り過ぎたか判定
      if(scroll >= target && scroll < targetPosition){
         //該当するhref属性にクラスを付与
        nav.find('a[href^="#' + id  + '"]').addClass('is-current');
      }else{
        //該当しないhref属性はクラスを削除
        nav.find('a[href^="#' + id  + '"]').removeClass('is-current');
      }
    });
  }
});

重要なポイントだけ紹介します。

  • 最初のif文「if(scroll >= navPosition)」は、ナビゲーションの位置までスクロールしたか判定しています。
    この指定をしている理由はナビゲーションの最初の要素に「is-current」クラスを付けておきたいためです。
  • 次のif文「if(scroll >= target && scroll < targetPosition)」は、該当するコンテンツまでスクロールしているのか判定、該当するコンテンツを通り過ぎたのか判定しています。
  • カレント表示をするためのクラスの付与方法については「id = $(e).attr('id');」でコンテンツのID属性を取得しているので、ナビゲーションのhref属性と一致するときだけ「is-current」を付与しています。

まとめ

追従ナビゲーションのカレント表示について紹介しました。
今回はサイドバーの追従ナビゲーションとして実装しましたが、ヘッダーを追従したい時にも応用できると思います。
よかったら参考にしてみてください。

あなたにおすすめの記事