Swiperを使用しているサイトでタブを実装する必要が出てきた時に、Swiperを利用したらタブも実装できるんじゃない??と思って制作しました。
いい感じに実装できたので、やり方を紹介していきます。
制作物を見る
以下が制作したものです。
See the Pen tab width swiper by takblog (@blanks-site) on CodePen.
タブの仕様
今回のタブは次のような仕様です。
- タブの切り替わりにはアニメーションが選択できる。
(Swiperのeffectから選択可能 Swiperのparameter) - URLパラメータによって、最初に表示するタブを制御できる。
タブ1を開く
タブ2を開く
タブの切り替わるアニメーションで選べるのがいいです。
flipなどにすると他とは違いを付けることができます。
flipバージョン
See the Pen tab width swiper flip by takblog (@blanks-site) on CodePen.
URLパラメータによるタブの制御
http://ドメイン/?tab=【index番号】で最初に表示できるタブを制御できます。
例えば http://ドメイン/?tab=1 で2番目のタブをロード時に表示できます。
URLパラメータの「tab」に関しては、jsの記述を変更すればパラメータの変更も可能です。
javascriptとhtml
html
<ul class="tab" id="tab" role="tablist">
<li class="tab-item" data-index="0" role="tab">タブ1</li>
<li class="tab-item" data-index="1" role="tab">タブ2</li>
<li class="tab-item" data-index="2" role="tab">タブ3</li>
<li class="tab-item" data-index="3" role="tab">タブ4</li>
</ul>
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide" role="tabpanel">
<div class="slide-inner">
<!-- タブ1 -->
</div>
</div>
<div class="swiper-slide" role="tabpanel">
<div class="slide-inner">
<!-- タブ2 -->
</div>
</div>
<div class="swiper-slide" role="tabpanel">
<div class="slide-inner">
<!-- タブ3 -->
</div>
</div>
<div class="swiper-slide" role="tabpanel">
<div class="slide-inner">
<!-- タブ4 -->
</div>
</div>
</div>
</div>
htmlの記述で大事なところは、タブのdata-indexです。
このdata-indexを取得して、表示するslideを決定してます。
data-indexは0から始めてください。
タブリストのidやタブのclassは後述のjavascriptの記述を変えれば変更できます。
javascript
/*
+-----------------+
| VARIABLE |
+-----------------+
*/
const tablistId = "tab"; //タブリストのID
const tabClass = "tab-item"; //タブのCLASS
const tabCurrentClass = "current"; //タブのカレントCLASS
const tabUrlparam = "tab"; //タブのURLパラメータ
/*
+-----------------+
| FUNCTION |
+-----------------+
*/
const tablistEle = document.getElementById(tablistId);
const tabbtnEles = document.getElementsByClassName(tabClass);
const tabSwiper = new Swiper('.swiper-container',{
autoHeight:true,
allowTouchMove:false,
effect:"fade",
fadeEffect: {
crossFade: true
}
});
//「tabItemclass」要素をクリックしたときに実行
for( let i = 0 ; i < tabbtnEles.length ; i++ ){
tabbtnEles[i].addEventListener("click",()=>{
const num = tabbtnEles[i].dataset.index;
const currentItem = tablistEle.getElementsByClassName(tabCurrentClass)[0];
currentItem.classList.remove(tabCurrentClass);
tabSwiper.slideTo(num);
tabbtnEles[i].classList.add(tabCurrentClass);
});
}
// URLパラメータ取得の関数 getParam
const getParam = (name, url) =>{
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
const regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
// Load時に最初に表示するタブの関数 initTab
const initTab = () =>{
const number = Number(getParam(tabUrlparam));
if( number != null && !(isNaN(number)) && 0 <= number && number < tabbtnEles.length){
tabSwiper.slideTo(number,0);
tabbtnEles[number].classList.add(tabCurrentClass);
}else{
tabbtnEles[0].classList.add(tabCurrentClass);
}
}
initTab();
簡単な説明をしていきます。
6~9行目
tablistIdは、タブリストのid名を入れます。html role="tablist" の要素を指定しています。
tabClassは、タブのclass名を入れます。html role="tab" の要素を指定しています。
tabCurrentClassは、タブがカレントになったときに追加されるclass名を入れます。
tabUrlparamは、ロード時にタブを制御するためのURLパラメータです。
19行目~:tabSwiper
今回のタブを実装する上で必要なオプションを入れています。
autoHeightはスライダーを表示中のスライドの高さに合わせてくれるオプションです。
falseだと一番コンテンツ量が多いスライドに合わせた高さになってしまうので、trueのほうがいいです。
allowTouchMoveはスワイプやマウス操作でスライドの切り替え行うかどうかを決定できるオプションです。
falseにしてスワイプやマウス操作でスライドが切り替わらないようにして、よりタブっぽくしています。
effectはスライドの切り替わりのアニメーションを決定できます。
"fade"の場合は、fadeEffectのcrossFadeをtrueにしないと上手く動かなかったので入れています。
他のeffectを使用する場合は、fadeEffectオプションは使いません。
28行目~:「tabItemclass」要素をクリックしたときに発火する関数
34行目のslideToはSwiperのメソッドで、指定したスライドに切り替えてくれるメソッドです。
「1」は1つ目のスライドでなく、2つ目のスライドです。
1つ目のスライドの時は、「0」なので気をつけてください。
39行目:getParam
こちらのJavascript でURLのパラメータを取得する方法を参考にさせてもらいました。
50行目:initTab
ロード時に最初に表示するタブを制御する関数です。
パラメータがなかったり、パラメータが正しい値ではなかったりする場合は、1枚目を表示するようにしています。
今回はSwiperをスライダーとしてではなく、タブとして使用してみました。
こんなことを想定して、allowTouchMoveのオプションはあるのだろうか?と開発者の用意周到さに驚きました!