複数タブをスマートに管理!簡単タブメニュー実装法【JavaScript・jQuery】

投稿日:

複数タブをスマートに管理!簡単タブメニュー実装法【JavaScript・jQuery】

Webサイトやアプリで「タブ切り替えUI」を取り入れたいとき、複数のタブグループを簡単に扱える仕組みがあると非常に便利です。
今回は、複数のタブメニューを1つのプログラムで一括管理でき、HTMLの可読性(読みやすさ)の高さが魅力の実装例をご紹介します。

タブメニューとは

タブのメニューをクリックすることで表示する内容を切り替えるUI(ユーザーインターフェイス)のことをタブメニューと言います。
 

 
タブメニューを用いることでHTMLの表示がすっきりする、ユーザーが見たい情報に早くアクセスできるなど様々な利点が挙げられます。

紹介するタブメニューの特徴

複数のタブリストをまとめて処理できる

このプログラムでは 「.tab_list」クラスを持つリストがページ内に複数あっても、自動的にそれぞれに対応するメニューを生成し、適切に切り替え動作をします。
これにより、1つのJavaScriptだけで複数タブメニューを扱えます。

ルナリス

ルナリス

コード1つで複数設置出来るわ

HTML構造が見やすい

タブのタイトルと内容は、以下のように隣接したHTML内に記述します。

<li class="tab_item">
	<p class="tab_title">タブ1</p>
	<div class="tab_cont">
		<p>タブ1の内容です。</p>
	</div>
</li>

エンジニアやデザイナーが構造を直感的に把握できるため、メンテナンス性が高まります。

他サイトのタブメニューとの差別点

他のブログ等で紹介されているタブメニューは1つの運用しか考慮されていない点や、メニュー部分と表示する中身を別々に記述することが多いです。
また、汎用性に欠けたり、可読性・メンテナンス性が低いです。
 

 
今回は、「ほとんど何も考えずに実装できる」を目指したタブメニューを構築しました。

ルナリス

ルナリス

コピペでOK!

使用例

HTML内に複数のタブメニューのHTMLを記述すると、それぞれに対応するメニューが自動生成されます。
このプログラムでは、各タブリストが独立して動作するため、例えば以下のようなレイアウトも簡単に実現可能です。
 

 

使用例

  • 商品情報とレビューを別々のタブに分けたい
  • よくある質問と操作マニュアルを分離表示したい
  • ページ内で複数の異なるタブUIを使いたい

サンプル

See the Pen
SimpleTabMenu-js
by 深井ルナリス (@kxdszxhx-the-decoder)
on CodePen.

ソースコード(JavaScript版)

HTML

<ul class="tab_list">
	<li class="tab_item">
		<p class="tab_title">タブ1</p>
		<div class="tab_cont">
			<p>タブ1の内容です。</p>
		</div>
	</li>
	<li class="tab_item">
		<p class="tab_title">タブ2</p>
		<div class="tab_cont">
			<p>タブ2の内容です。</p>
		</div>
	</li>
	<li class="tab_item">
		<p class="tab_title">タブ3</p>
		<div class="tab_cont">
			<p>タブ3の内容です。</p>
		</div>
	</li>
</ul>

<ul class="tab_list">
	<li class="tab_item">
		<p class="tab_title">タブA</p>
		<div class="tab_cont">
			<p>タブAの内容です。</p>
		</div>
	</li>
	<li class="tab_item">
		<p class="tab_title">タブB</p>
		<div class="tab_cont">
			<p>タブBの内容です。</p>
		</div>
	</li>
	<li class="tab_item">
		<p class="tab_title">タブC</p>
		<div class="tab_cont">
			<p>タブCの内容です。</p>
		</div>
	</li>
</ul>

CSS

.tab_menu, .tab_list {
	list-style-type: none;
	padding: 0;
	margin: 0;
	width: 100%;
}
.tab_menu {
	display: flex;
}
.tab_menu li {
	cursor: pointer;
	background-color: #c5c5c5a6;
	padding: 15px;
	font-size: 18px;
	min-width: 150px;
	text-align: center;
	font-weight: bold;
	border: solid 1px #b1b1b1;
	border-right: none;
	user-select: none;
}
.tab_menu li.active {
	background-color: #fff;
}
.tab_menu li:last-child {
	border-right: solid 1px #b1b1b1;
}
.tab_list {
	border: solid 1px #b1b1b1;
	margin-bottom: 45px;
}
.tab_title {
	display: none;
}
.tab_item {
	display: none;
	padding: 30px 1.5%;
}
.tab_item.active {
	display: block;
}

JavaScript

const tabLists = document.querySelectorAll('.tab_list');


tabLists.forEach((tabList) => {
    const tabItems = tabList.querySelectorAll('.tab_item');
    const tabTitles = tabList.querySelectorAll('.tab_title');
    const tabMenu = document.createElement('ul');
    tabMenu.className = 'tab_menu';

    tabTitles.forEach((title, i) => {
        const tabMenuItem = document.createElement('li');
        tabMenuItem.innerText = title.innerText;

        tabMenuItem.addEventListener('click', () => {
            const tabMenuItems = tabMenu.querySelectorAll('li');
            tabMenuItems.forEach((li) => li.classList.remove('active'));
            tabItems.forEach((li) => li.classList.remove('active'));
            tabMenuItems[i].classList.add('active');
            tabItems[i].classList.add('active');
        });

        tabMenu.appendChild(tabMenuItem);
    });

    if ( tabItems.length > 0 ) {
        tabItems[0].classList.add('active');
    }
    const firstMenuItem = tabMenu.querySelector('li');
    if ( firstMenuItem !== null ) {
        firstMenuItem.classList.add('active');
    }

    tabList.before(tabMenu);
});

簡単な解説

「ul.tab_list(タブメニュー1かたまり)」ごとにタブのメニューとその中身を記述します。
JavaScriptで「.tab_title」の要素をメニューとして再構築し、クリックイベントも付与することでタブメニューを実装しています。
 

 
ul.tab_listの数だけループ処理をしているため、複数のタブメニューの実装も対応済みです。

jQuery版

html, cssは共通です。

$(function() {
    $('.tab_list').each(function() {
        var $tabList = $(this);
        var $tabItems = $tabList.find('.tab_item');
        var $tabTitles = $tabList.find('.tab_title');

        var $tabMenu = $('<ul></ul>', { 'class': 'tab_menu' });

        $tabTitles.each(function(index) {
            var $title = $(this);
            var $tabMenuItem = $('<li></li>').text($title.text());

            $tabMenuItem.on('click', function() {
                $tabMenu.find('li').removeClass('active');
                $tabItems.removeClass('active');
                $(this).addClass('active');
                $tabItems.eq(index).addClass('active');
            });

            $tabMenu.append($tabMenuItem);
        });

        if ($tabItems.length > 0) {
            $tabItems.eq(0).addClass('active');
        }

        var $firstMenuItem = $tabMenu.find('li').eq(0);
        if ($firstMenuItem.length > 0) {
            $firstMenuItem.addClass('active');
        }

        $tabList.before($tabMenu);
    });
});

まとめ

このタブメニュー実装は、

  • 可読性の高いHTML構造
  • 複数タブメニューへの対応
  • シンプルなJavaScriptロジック

という3点で非常に実用的です。
小規模サイトから中規模の情報整理まで、柔軟に対応できる汎用性の高いパターンなので、ぜひ導入してみてください!

コメント一覧

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です