この記事は2020年3月4日に書かれたもので、内容が古く現在では推奨されていない方法の可能性もありますのでご注意ください。
jQueryを使ってタブ切り替えを実装するサンプルを作ってみました。アニメーションもjQueryで実装しようかとも思いましたが、最終的にCSSでの実装としました。
別記事のCSSとhtmlのradioボタンを使ってタブ切り替えを実装するサンプルと、ネイティブのJavaScript(脱jQuery)でタブ切り替えを実装するサンプルとの比較も兼ねて作ったので、htmlは似た構成にしています。
html
<ul class="tab-menu">
<li class="tab-menu__item"><span class="tab-trigger js-tab-trigger is-active" data-id="tab01">タブ1</span></li>
<li class="tab-menu__item"><span class="tab-trigger js-tab-trigger" data-id="tab02">タブ2</span></li>
<li class="tab-menu__item"><span class="tab-trigger js-tab-trigger" data-id="tab03">タブ3</span></li>
</ul><!-- .tab-menu -->
<div class="tab-content">
<div class="tab-content__item js-tab-target is-active" id="tab01">
<p>タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。</p>
</div><!-- .tab-content__item -->
<div class="tab-content__item js-tab-target" id="tab02">
<p>タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。</p>
</div><!-- .tab-content__item -->
<div class="tab-content__item js-tab-target" id="tab03">
<p>タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。</p>
</div><!-- .tab-content__item -->
</div><!-- .tab-content -->
タブを切り替えるボタン要素(トリガーになる要素)は’.tab-trigger’、タブのコンテンツ(表示を切り替える要素)はここでは’.tab-content__item’という構成です。
タブ切り替えの要素はaタグにして、hrefでコンテンツ要素のIDを指定する方法も考えましたが、今回はspanタグにしてdata-idというdata属性を使用することで対応しました。
それぞれ、JavaScriptを使用して動かす要素になるので、JavaScriptでの操作のために ‘js-‘ というプレフィックスをつけた’.js-tab-trigger’, ‘.js-tab-target’というクラスをそれぞれにつけています。
CSS
/* タブメニュー */
.tab-menu {
display: flex;
margin: 0 -5px;
}
.tab-menu__item {
box-sizing: border-box;
padding: 0 5px;
}
.tab-trigger { /* label */
text-align: left;
cursor: pointer;
display: block;
padding: 10px;
border: 1px solid #ccc;
border-bottom: 0;
border-radius: 5px 5px 0 0;
overflow: hidden;
background-color: lightgray;
position: relative;
}
.tab-trigger.is-active {
background-color: lightblue;
}
/* タブコンテンツ */
.tab-content {
border: 1px solid #ccc;
}
.tab-content__item {
box-sizing: border-box;
padding: 20px;
display: none;
text-align: left;
}
.tab-content__item.is-active {
display: block;
animation: fade 0.5s ease;
}
@keyframes fade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
トリガー要素がaタグではないためcursor: pointerを付与。アニメーションをCSSでつけているので、タブコンテンツ要素のアクティブ時のクラス’.is-active’に@keyframesで作成したフェードアニメーションを付加しています。
JavaScript
jQueryで動かしているので、忘れずにjQueryを読み込みます。今回はCDNで埋め込んでいます。
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
$(function(){
$('.js-tab-trigger').on('click', function (e) {
// すべてのタブメニューの'is-active'クラスを削除
$('.js-tab-trigger').removeClass('is-active');
// クリックしたタブメニューに'is-active'クラスを追加
$(this).addClass('is-active');
// ターゲットとなる要素(タブメニューdata属性値と等しいid値を持つコンテンツ要素[ターゲット要素])を取得
let currentContent = $('#' + $(this).data('id'));
// タブコンテンツを非アクティブにする
$('.js-tab-target').removeClass('is-active');
// 対象コンテンツ(指定したIDの要素があったら)を表示させる
if (currentContent.length) {
currentContent.addClass('is-active');
}
});
});
トリガー要素の’.js-tab-trigger’がクリックされたら、タブメニュー全てのアクティブクラスの’.is-active’を削除、クリックされた要素にのみ’.is-active’を付加し、タブコンテンツ要素を表示するためのdata-id属性を取得します。
コンテンツ要素も一度、全ての要素から’.is-active’を削除し、クリック要素から取得したIDの要素があった場合、’.is-active’を付加し、表示する形にしました。
別の方法でタブの親要素をを取得して、兄弟要素から対象要素を判定、クラス付与する方法もあり、そちらの方がもしかしたら汎用的かもしれませんが、今回はアニメーションもCSSに任せているので、シンプルにタブ要素と、コンテンツ要素で操作するようにしました。
コメント
まだ、コメントはありません。