今回は「外部ファイル(html)からコンテンツを読み込んで表示するタブ」を実装します。
タブ機能って、簡単なものは同一ページ内にそれぞれのコンテンツ内容が記述されていて、「display:none;」や「display:block;」で表示/非表示を切り替えています。
しかしコンテンツ内容が多くなると、これではページの読み込みが遅くなってしまいがちです。
そこでコンテンツ内容を外部ファイル化することで、ページの読み込みを早くして、またコンテンツを管理をしやすくします。
今回のスクリプトの注意点や機能は以下のものです。

  • jQuery使用
  • タブ切替によって表示するコンテンツを外部ファイルから読み込む
  • urlパラメータによってロード時に表示するコンテンツの制御
  • コンテンツはスライドアップ/スライドダウンで切替


制作コードと使い方

まずは制作したものを記載します。
以下にはjavascriptとhtmlしか記載していませんので、他のファイルはこちらのgithubから確認してください。

使い方はこちら

script.js
ポップアップでコードを見る

コードをクリップボードにコピー
/* ===========================================
  定数定義
===========================================*/
const tabItemClass = 'glossarytab-item';             // タブ要素のクラス名
const tabItemSelectClass = 'glossarytab-selected';   // タブ選択時にタブ要素に付与されるクラス名
const tabContentsId = 'glossaryContents';            // 読み込みコンテンツを表示する要素のid名

/* ===========================================
  変数定義
===========================================*/
let intItemPath = 'tab/tab1.html';                   // ロード時に読み込むコンテンツの初期値
let intItemTab = '[data-tab="'+ intItemPath +'"]';   // ロード時にtabItemSelectClassを付与するtabItemClass要素の初期値

/* ===========================================
  関数定義
===========================================/

/*---------------------------------------------------
 ロード時に発火する関数
 urlパラメータで「?tab=x」となっている場合 (x-1)番目の【tabItemClass】要素の「data-tab」に設定されているコンテンツを読み込む
---------------------------------------------------*/
function pageLoad(){
  //urlパラメータを'&'区切りで配列urlParametersを生成
  const urlParameters = location.search.slice(1).split('&');

  // urlパラメータがあった場合の処理
  if( urlParameters[0] != "" ){    
    parameterArray = new Array; 
          
    // urlParametersから連想配列 parameterArray を生成
    // パラメータ ?key=value を parameterArray[key] = value となるように parameterArray に入れていく。
    for( i in urlParameters ){
      let y = urlParameters[i].split('=');
      parameterArray[y[0]] = y[1];    }
    
    // parameterArray["tab"]の値 が undefined でない かつ parameterArray["tab"]の値が【tabItemClass】の要素数より小さい場合
    if( parameterArray["tab"] != undefined && parameterArray["tab"] < $('.'+tabItemClass).length ){
      let intItemPath = $('.'+tabItemClass).eq(parameterArray["tab"]).attr("data-tab");
      let intItemTab = '[data-tab="'+ intItemPath +'"]';
      tabLoad(intItemPath,intItemTab);
    }else{      
      let intItemTab = '[data-tab="'+ intItemPath +'"]';
      tabLoad(intItemPath,intItemTab);
    }
  }else{  
  // urlパラメータがなかった場合の処理
    let intItemTab = '[data-tab="'+ intItemPath +'"]';
    tabLoad(intItemPath,intItemTab);  
  }
}


/*---------------------------------------------------
ロード時に読み込むコンテンツと、タブに【tabItemSelectClass】を付与する関数
---------------------------------------------------*/
function tabLoad(intItemPath,intItemTab){
  $('.'+tabItemClass+intItemTab).addClass(tabItemSelectClass);
  $.ajax(intItemPath,{
    type: 'get',
    dataType: 'html'
  }).done(function(data){
    $('#'+tabContentsId).append('<div id="'+tabContentsId+'-current">'+data+'</div>');
  });
}


/*---------------------------------------------------
タブをクリックしたときに発火する関数
---------------------------------------------------*/
function tabClick(){
  $('.'+tabItemClass).on('click',function(){
    let contentsPath = $(this).attr('data-tab');                                         // クリックしたタブの「data-tab」を取得
    $('.'+tabItemClass+'.'+tabItemSelectClass).removeClass(tabItemSelectClass);          // 選択されていたタブからクラス【tabItemSelectClass】を除去
    $(this).addClass(tabItemSelectClass);                                                // クリックしたタブに【tabItemSelectClass】を付与  
    $.ajax(contentsPath,{
      type: 'get',
      dataType: 'html'
    }).done(function(data){
      $.when(
        $('#'+tabContentsId+'-current').slideUp(),                                       // 表示されていたコンテンツ内容(contents1)をスライドアップで非表示
        $('#'+tabContentsId).append('<div id="'+tabContentsId+'-next">'+data+'</div>')   // 【tabContentsId】の中に、次に表示するコンテンツ内容(contents2)を追加
      ).done(function(){
        $.when(
          $('#'+tabContentsId+'-next').slideDown(),                                      //contents2をスライドダウンで表示
        ).done(function(){
          $('#'+tabContentsId+'-current').remove();                                      //contents1をhtmlから削除                                     
          $('#'+tabContentsId+'-next').attr('id',''+tabContentsId+'-current');           //contents2のid名を「【tabContentsId】-next」から「【tabContentsId】-current」に変更
        });
      });
    });
  });
}


/* ===========================================
  関数実行
===========================================*/
$(function(){
  pageLoad();
  tabClick();
});

index.html
ポップアップでコードを見る

コードをクリップボードにコピー
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
#wrapper{
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  padding: 50px 10px;
  margin: 0 auto;
  width: 100%;
  max-width: 900px;
}
#glossaryContents-next{
  display: none;
}
 #glossarytab {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap; }
   #glossarytab .glossarytab-item {
    list-style: none;
    -webkit-box-flex: 0;
    -ms-flex: 0 0 80px;
    flex: 0 0 80px;
    width: 80px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    border: 1px solid #40210f;
    margin: 0 1rem 1rem 0;
    cursor: pointer; }
     #glossarytab .glossarytab-item {
      -webkit-transition: .2s opacity ease-in;
      -o-transition: .2s opacity ease-in;
      transition: .2s opacity ease-in;
      cursor: pointer; }
       #glossarytab .glossarytab-item:hover {
        opacity: .4; }
     #glossarytab .glossarytab-item.glossarytab-selected {
      background-color: #40210f;
      color: #fff; }
</style>
</head>
<body>
<div id="wrapper">
  <!-- タブ要素 -->
  <ul id="glossarytab">
    <li class="glossarytab-item" data-tab="tab/tab1.html">tab1</li>
    <li class="glossarytab-item" data-tab="tab/tab2.html">tab2</li>
    <li class="glossarytab-item" data-tab="tab/tab3.html">tab3</li>
    <li class="glossarytab-item" data-tab="tab/tab4.html">tab4</li>
  </ul>
  <div id="glossaryContents">
    <!-- コンテンツが読み込まれる場所 -->
    
  </div>
</div>
<script
  src="//code.jquery.com/jquery-3.3.1.min.js"
  integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
  crossorigin="anonymous"></script>
<script src="script.js" charset="utf-8"></script>
</body>
</html>

使い方

このタブの使い方を説明します。
まずhtmlファイルから説明していきます。

  <ul id="glossarytab">
    <li class="glossarytab-item" data-tab="tab/tab1.html">tab1</li>
    <li class="glossarytab-item" data-tab="tab/tab2.html">tab2</li>
    <li class="glossarytab-item" data-tab="tab/tab3.html">tab3</li>
    <li class="glossarytab-item" data-tab="tab/tab4.html">tab4</li>
  </ul>  

クラス名「glossarytab-item」の要素に「data-tab」があります。
この値が「glossarytab-item」がクリックされた時に読み込まれるhtmlファイルです。「data-tab」はファイルのパスを記述してください。
例では相対パスで記述していますが、絶対パスでも問題ありません。

id名「glossaryContents」内に読み込まれるコンテンツの内容が表示されます。できればこの要素は空にしておいてください。

htmlファイルの説明は以上です。


次にjsファイルの説明をしていきます。

/* ===========================================
  定数定義
===========================================*/
const tabItemClass = 'glossarytab-item';             // タブ要素のクラス名
const tabItemSelectClass = 'glossarytab-selected';   // タブ選択時にタブ要素に付与されるクラス名
const tabContentsId = 'glossaryContents';            // 読み込みコンテンツを表示する要素のid名

【tabItemClass】はタブ要素のクラス名
【tabItemSelectClass】はタブ選択時にタブ要素に付与されるクラス名
【glossaryContents】は読み込みコンテンツを表示する要素のid名
を入れます。

/* ===========================================
  変数定義
===========================================*/
let intItemPath = 'tab/tab1.html';                   // ロード時に読み込むコンテンツの初期値
let intItemTab = '[data-tab="'+ intItemPath +'"]';   // ロード時にtabItemSelectClassを付与するtabItemClass要素の初期値

【intItemPath】には最初に読み込まれるコンテンツのパスを入れます。


urlパラメータによってロード時に表示するコンテンツを制御する

別ページから、こちらで紹介しているタブ機能を実装したページに遷移するときにurlパラメータを付けると好きなタブコンテンツを表示できます。
例えば「https://blanks.site/tab.html?tab=2」とリンクさせると、ロード時に3番目のタブが選択され、3番目のタブの「data-tab」に設定されているコンテンツが読み込まれます。


ぜひ、このタブ機能をお使いくださいませ〜。