【jQuery】スクロール時に追従するナビゲーションボタンを実装する(コピペで簡単)

この記事を書いている僕は、フロントエンドエンジニア歴が15年ほど。

web業界からゲーム業界まで数多くのwebサイトやアプリケーションを制作しています。

こういった僕が、分かりやすく解説していきます。

今回の追従するナビゲーションボタンは【jQuery】タブ切り替え機能を実装する(コピペで簡単)のタブ切り替えボタンを追従するよう実装しています。

読者の悩み

  • jQueryを使ってスクロール時に上部に固定されてついてくるナビゲーションを実装したい
  • トップからある要素のタグまでスクロールしたら追従させるようにしたい
  • 簡単で色々なUI作成に応用できる便利なサンプルないかな

こういった疑問に答えます。

本記事の内容

  • jQueryでスクロール時に上部に固定されるナビゲーションの実装方法をコードで解説
  • デモページとサンプルコードで確認しながらコピペできます
  • シンプルでカスタマイズやメンテナンスもしやすく簡単に作れます

デモページを用意

デモページを用意してますので実際に動きが確認できます。

DEMO

サンプルコードを用意

コード[HTML / SCSS / CSS / jQuery]をGitHubの方でも確認できます。

実際のソースコードをアップしているのでクローンしてもOKです。

phpファイル
scssファイル
jsファイル
cssファイル

デモページとソースコードを確認しながらご覧ください。

骨組みは以下の5つです。

  • 追従タブのクリックイベント
  • 追従タブの情報を取得
  • 既存タブの連携
  • 追従タブの表示処理(ヘッダー固定)
  • スクロール処理

ではコードを見ていきます。

追従タブのクリックイベント

既存タブとは別の追従タブ用のコードを追加します。

<nav id="ji-tabNavi" class="c-tab-navi">
  <ul class="c-tab-navi__inner">
    <li id="tabNaviDetail" class="c-tab-navi__button jc-tab02 js-active"><a href="#ji-tab-1">DESIGN</a></li>
    <li id="tabNaviTable" class="c-tab-navi__button jc-tab02"><a href="#ji-tab-2">CODING</a></li>
  </ul>
</nav>
$('.jc-tab02 a').on('click', function () {
  $(this).parent().addClass('js-active').siblings('.js-active').removeClass('js-active');
  var jc_tabContent02 = $(this).attr('href');
  $(jc_tabContent02).addClass('js-show').siblings('.js-show').removeClass('js-show');
    ︙
});

id名やクラス名を追従切り替え用に変更しているだけで、既存タブとやっていることはほぼ同じです。【jQuery】タブ切り替え機能を実装する(コピペで簡単)

.c-tab-navi {
    ︙
  display: none;
}

追従タブを非表示にしておきます。

追従タブと既存タブの情報を取得

追従タブと既存タブの切り替えを行うために、タブがクリックされた時の情報を取得し変数に代入します。

$('.jc-tab a').on('click', function () {
    ︙
  //追従タブの情報を取得
  var tabNaviCheckerDetail = $('#tabNaviDetail').hasClass('js-active');
  var tabNaviCheckerTable = $('#tabNaviTable').hasClass('js-active');
    ︙
});

追従タブのid属性に対して引数に指定されたクラス名が付与されているか確認し変数に代入します。

$('.jc-tab02 a').on('click', function () {
    ︙
  //既存のタブの情報を取得
  var tabcheckerDetail = $('#tabDetail').hasClass('js-active');
  var tabcheckerTable = $('#tabTable').hasClass('js-active');
    ︙
});

既存タブのid属性に対して引数に指定されたクラス名が付与されているか確認し変数に代入します。

追従タブと既存タブの連携

タブの切り替えを連携させるために、下図のような条件分岐を行います。「if, else if」を組み合わせて実装していきます。

$('.jc-tab a').on('click', function () {
    ︙
  //追従タブを切替
  if (tabNaviCheckerDetail) {
    $('#tabNaviDetail').removeClass('js-active');
    $('#tabNaviTable').addClass('js-active');
  } else if (tabNaviCheckerTable) {
    $('#tabNaviDetail').addClass('js-active');
    $('#tabNaviTable').removeClass('js-active');
  }
    ︙
});

既存タブと同じ切り替えを追従タブにも反映させます。

$('.jc-tab02 a').on('click', function () {
    ︙
  //既存タブを切替
  if (tabcheckerDetail) {
    $('#tabDetail').removeClass('js-active');
    $('#tabTable').addClass('js-active');
  } else if (tabcheckerTable) {
    $('#tabDetail').addClass('js-active');
    $('#tabTable').removeClass('js-active');
  }
    ︙
});

追従タブと同じ切り替えを既存タブにも反映させます。

追従タブの表示処理(ヘッダー固定)

jQueryで特定の要素が存在するかどうかを判別する処理は【.length】で判定できます。

追従タブがある場合にスクロールイベントを実行させます。

//追従ボタンが存在する場合
if ($('#ji-tabNavi').length) {
  $(window).on('scroll', function () {
    //スクロール位置取得
    const scrollTop = $(window).scrollTop();
    //追従範囲のtop位置取得
    const containerTop = $('#ji-tabContainer').offset().top;
    //追従範囲のbottom位置取得
    const containerBottom = $('#ji-tabContainer').height() + $('#ji-tabContainer').offset().top;
    //追従範囲内で表示
    if (scrollTop > containerTop && scrollTop < containerBottom) {
      $('#ji-tabNavi').show();
    } else {
      $('#ji-tabNavi').hide();
    }
  });
}

scrollTop()

画面をスクロールした時のスクロール量を取得することができます。

offset().top

画面左上からHTML要素までの距離を取得できるメソッドになります。

height()

HTML要素の高さを取得・設定することができるメソッドになります。

スクロール位置と追従範囲のtop位置とbottom位置を取得します。

bottom位置はheight()とoffset().topで距離を取得します。

条件分岐で追従範囲内でタブを表示するようにします。

.c-tab-navi {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 200;
    ︙
}

追従ボタンがある場合に画面上のTOPに固定させて追従させています。

スクロール処理

最後に、aタグを押した時にスムーズにスクロールするようにアニメーションを設定します。

$('a[href^="#"]').click(function () {
  var speed = 400; // ミリ秒
  var href = $(this).attr("href");
  var target = $(href == "#" || href == "" ? "html" : href);
  var position = target.offset().top;
  $("body,html").animate({ scrollTop: position }, speed, "swing");
  return false;
});

対象要素.animate( CSSプロパティ, duration, easing, 関数 )

animate()は、特定のHTML要素のCSSプロパティを連続して変化させることでアニメーションを実現してくれます。

CSSプロパティ

オブジェクト形式で記述する必要があります。

変数positionを設定してリンクの距離をスクロールするアニメーションを調整します。

duration

ミリ秒で指定するようになっており、アニメーションが完了するまでの時間を設定できます。

変数speedを設定してアニメーション時間を調整します。

easing

アニメーションの挙動を指定可能で、「linear」と「swing」の2種類を文字列で設定します。

「swing」はeasingで、エフェクトの動きを加速/減速させるための関数です。

関数

引数にはコールバック関数を設定することができるのですが、今回は設定していないので割愛させていただきます。

上記のように、各変数を設定して値を代入し、animate()イベントで引数で指定します。

今回は以上になります。

作成方法が不安な方は是非参考にしていただけると嬉しいです。

一覧へ

Recommended