この記事を書いている僕は、フロントエンドエンジニア歴が15年ほど。
web業界からゲーム業界まで数多くのwebサイトやアプリケーションを制作しています。
こういった僕が、分かりやすく解説していきます。
今回の追従するナビゲーションボタンは【jQuery】タブ切り替え機能を実装する(コピペで簡単)のタブ切り替えボタンを追従するよう実装しています。
読者の悩み
こういった疑問に答えます。
本記事の内容
デモページを用意
デモページを用意してますので実際に動きが確認できます。
サンプルコードを用意
コード[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()
スクロール位置と追従範囲の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()は、特定のHTML要素のCSSプロパティを連続して変化させることでアニメーションを実現してくれます。
CSSプロパティ
オブジェクト形式で記述する必要があります。
変数positionを設定してリンクの距離をスクロールするアニメーションを調整します。
duration
ミリ秒で指定するようになっており、アニメーションが完了するまでの時間を設定できます。
変数speedを設定してアニメーション時間を調整します。
easing
アニメーションの挙動を指定可能で、「linear」と「swing」の2種類を文字列で設定します。
「swing」はeasingで、エフェクトの動きを加速/減速させるための関数です。
関数
引数にはコールバック関数を設定することができるのですが、今回は設定していないので割愛させていただきます。
上記のように、各変数を設定して値を代入し、animate()イベントで引数で指定します。
今回は以上になります。
作成方法が不安な方は是非参考にしていただけると嬉しいです。