JavaScript - タブメニューの作り方
ウェブページに表示する内容を簡単に切り替えることができるタブメニューを作ります。JavaScript の forEach() メソッドと for...of ループの反復処理でクラスの付け外しを行う方法を学びましょう。
タブメニューとは?
タブメニューは、関連する複数のコンテンツを重ねて表示する仕組みです。見出しとなるタブをクリックすると、画面に表示する内容を切り替えることができます。ウェブサイトなどでよく見られますよね。
今回紹介するのは、JavaScript を使ってタブメニューを作る方法です。タブを三つ用意して、クリックしたら表示内容が切り替わるようにコーディングします。
この記事を読むと分かること
querySelectorAll()
forEach()
for...of
ループclassList.remove()
classList.add()
サンプルプロジェクト
これから作っていくのは、下のようなタブメニューです。タブメニューは、見出しとして並んでいるタブの部分と、それに対応するコンテンツで成り立っています。
HTML
まずは、HTML を書きましょう。ここでは、見出しとなるタブを <h2>
要素で三つ作ります。最初に表示したい Tab 1 には、class="active"
を指定しておきます。
<div class="container">
<!--見出しとなるタブ-->
<div class="tabMenu">
<h2 class="tab active">Tab 1</h2> <!--最初に表示-->
<h2 class="tab">Tab 2</h2>
<h2 class="tab">Tab 3</h2>
</div>
</div>
タブを三つ作ったので、画面に表示するコンテンツも三つ作りましょう。Tab 1 に対応するコンテンツにも class="active"
を指定してくださいね。
<div class="container">
<div class="tabMenu">
<h2 class="tab active">Tab 1</h2>
<h2 class="tab">Tab 2</h2>
<h2 class="tab">Tab 3</h2>
</div>
<!--画面に表示するコンテンツ-->
<div class="tabContent">
<div class="content active"> <!--最初に表示-->
<p>タブ1のコンテンツ</p>
</div>
<div class="content">
<p>タブ2のコンテンツ</p>
</div>
<div class="content">
<p>タブ3のコンテンツ</p>
</div>
</div>
</div>
以上で HTML ができました。ブラウザには以下のように表示されます。
CSS
続いて、CSS です。見出しとなるタブを横並びにしましょう。画面に表示するコンテンツは、三つとも非表示にしておきますよ。
body {
margin: 0;
padding: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
}
.container {
width: 500px;
height: 250px;
border: 5px solid lightgray;
}
.tabMenu {
display: flex;
justify-content: center;
align-items: center;
height: 70px;
background-color: #ED7E07; /*オレンジ色*/
}
/*タブを横に並べる*/
.tab {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
.tabContent {
padding: 10px 40px;
font-size: 20px;
}
/*コンテンツは非表示*/
.content {
display: none;
}
ブラウザには以下のように表示されます。すべてのタブの背景色はオレンジ色で、コンテンツは何も表示されていません。
先ほど HTML を書いたときに、Tab 1 とそれに対応するコンテンツに class="active"
を指定しておきましたね。active
クラスがついている場合は、タブの色を変えてコンテンツが表示されるように、CSS を追加しましょう。
/*activeクラスの追加でタブの色を変更*/
.tab.active {
color: #ED7E07;
background-color: white;
}
/*activeクラスの追加でコンテンツを表示*/
.content.active {
display: block;
}
アクティブなタブは文字がオレンジ色で背景色は白、アクティブなコンテンツは画面に表示されるようになりました。
次のセクションからは、タブメニューに動きをつけるための JavaScript を書いていきます。
JavaScript
JavaScript では、タブとコンテンツの active
クラスを削除/追加して、表示を切り替えられるようにしていきます。次の手順でコードを書いていきましょう。
- 要素を取得する
- タブにイベントリスナーを設定する
- すべての
active
クラスを削除する - クリックされた要素に
active
クラスを追加する
要素を取得する
JavaScript で操作するのは、三つのタブと三つのコンテンツです。すべてのタブとコンテンツを querySelectorAll()
メソッドで取得して変数に格納しておきましょう。
//すべてのtab要素を取得し、変数tabsに格納する
const tabs = document.querySelectorAll('.tab');
//すべてのcontent要素を取得し、変数contentsに格納する
const contents = document.querySelectorAll('.content');
タブにイベントリスナーを設定する
表示を切り替えるためには、どのタブがクリックされたのか、どのタブにクリックイベントが発生したのかを知る必要があります。そのために、tab
要素それぞれにイベントリスナーを設定しますよ。
変数 tabs
に格納されている tab
要素一つひとつにクリックイベントを追加するために、forEach()
メソッドを使いましょう。forEach()
は、括弧 ()
に指定した関数を各要素に対して一度ずつ実行するメソッドです。
//すべてのtab要素に関数を実行する
tabs.forEach(function() {
/*=====================================
タブにクリックイベントを追加、
クリックイベントが発生したら表示を切り替える処理
=====================================*/
});
forEach()
メソッドで実行する関数には引数を指定します。これは、処理の対象となる要素を順番に受け取るための変数です。ここでは tab
要素が対象となるので、tab
という名前で引数を指定します。
tabs.forEach(function(tab)) {
});
今回はもう一つ引数を指定しますよ。forEach()
メソッドで実行する関数に二つ目の引数を指定すると、処理の対象となっている要素のインデックス番号を受け取ることができます。カンマ ,
に続けて index
を追加しましょう。
tabs.forEach(function(tab,index)) {
});
tab
要素それぞれにクリックイベントを追加するコードは、以下のようになります。タブがクリックされたら、表示を切り替える toggleClass
という関数が実行されるようにします。
tabs.forEach(function(tab,index) {
//タブにクリックイベントを追加
tab.addEventListener('click', toggleClass);
/*=========================================
タブがクリックされたときに実行する関数toggleClass
=========================================*/
});
すべての active クラスを削除する
タブがクリックされたらタブとコンテンツの表示が切り替わるよう、関数 toggleClass
を定義していきましょう。
tabs.forEach(function(tab,index) {
tab.addEventListener('click', toggleClass);
//タブがクリックされたときに実行する関数
function toggleClass() {
/*==============================
タブとコンテンツの表示を切り替える処理
==============================*/
}
});
表示を切り替えるためには、まず、一旦すべてのタブとコンテンツをアクディブではない状態にします。要素.classList.remove('active')
と書くと、active
クラスを削除することができます。すべての tab
要素と content
要素から active
クラスを削除するために、ここでは for...of
ループを使いましょう。
tabs.forEach(function(tab,index) {
tab.addEventListener('click', toggleClass);
function toggleClass() {
//すべてのタブからactiveクラスを削除する
for(const tab of tabs){
tab.classList.remove('active');
}
//すべてのコンテンツからactiveクラスを削除する
for(const content of contents){
content.classList.remove('active');
}
}
});
for...of
ループについては、こちらの記事を参考にしてください。
active
クラスが削除されると、タブメニューはアクティブではない状態になります。
クリックされた要素に active クラスを追加する
最後に、クリックされたタブとそのコンテンツだけをアクティブな状態にします。アクティブな状態にするためには、要素.classList.add('active')
として active
クラスを追加します。
クリックされた tab
要素とそのインデックスは、forEach()
メソッドで実行する関数に指定した引数 tab
と index
でアクセスすることができますよ。クリックされた tab
要素に active
クラスを追加するコードは、以下のようになります。
//クリックされたtab要素にactiveクラスを追加する
tab.classList.add('active');
表示するコンテンツは、クリックされた tab
要素のインデックスで指定します。contents[index]
とすることで、1番目のタブがクリックされたら1番目の content
要素に、2番目のタブがクリックされたら2番目の content
要素に active
クラスが追加され、画面に表示されます。
//クリックされたtab要素と同じインデックスを持つcontent要素にactiveクラスを追加する
contents[index].classList.add('active');
以上で、関数 toggleClass
を定義できました。タブがクリックされると、タブとコンテンツの active
クラスを削除/追加する処理が行われ、表示が切り替わります。
tabs.forEach(function (tab,index) {
tab.addEventListener('click', toggleClass);
//タブがクリックされたときに実行する関数
function toggleClass() {
//すべてのタブとコンテンツからactiveクラスを削除する
for(const tab of tabs){
tab.classList.remove('active');
}
for(const content of contents){
content.classList.remove('active');
}
//クリックされたタブとそのコンテンツにactiveクラスを追加する
tab.classList.add('active');
contents[index].classList.add('active');
}
});
完成コード
タブ切り替えメニューのコードが完成です。
/***************************/
/* タブ切り替えメニューのコード */
/***************************/
const tabs = document.querySelectorAll('.tab');
const contents = document.querySelectorAll('.content');
tabs.forEach(function (tab,index) {
tab.addEventListener('click', toggleClass);
function toggleClass() {
for(const tab of tabs){
tab.classList.remove('active');
}
for(const content of contents){
content.classList.remove('active');
}
tab.classList.add('active');
contents[index].classList.add('active');
}
});
上と同じ内容をアロー関数を使って書くと、下のようになります。function キーワードが不要になるので、スッキリしたコードになりますね。
/**************************************/
/* タブ切り替えメニューのコード アロー関数使用*/
/**************************************/
const tabs = document.querySelectorAll('.tab');
const contents = document.querySelectorAll('.content');
tabs.forEach((tab,index) => {
tab.addEventListener('click', () => {
for(const tab of tabs){
tab.classList.remove('active');
}
for(const content of contents){
content.classList.remove('active');
}
tab.classList.add('active');
contents[index].classList.add('active');
});
});
forEach() メソッドと for…of ループ
さて、今回は、複数の要素に同じ処理を繰り返し行うために forEach()
メソッドと for...of
ループを使いました。forEach()
メソッドには、for...of
ループと違って、対象となる要素だけでなくそのインデックスにもアクセスできるという特徴があります。今回はその違いを区別するために、forEach()
メソッドと for...of
ループを両方使いました。
//反復処理forEach()
tabs.forEach((tab,index) => {
tab.addEventListener('click', () => {
//反復処理for...of
for(const tab of tabs){
tab.classList.remove('active');
}
//反復処理for...of
for(const content of contents){
content.classList.remove('active');
}
tab.classList.add('active');
contents[index].classList.add('active');
});
});
for...of
ループを使わずに、すべての反復処理を forEach()
メソッドで書くと、下のようになりますよ。
//反復処理forEach()
tabs.forEach((tab,index) => {
tab.addEventListener('click', () => {
//反復処理forEach()
tabs.forEach(tab => tab.classList.remove('active'));
//反復処理forEach()
contents.forEach(content => content.classList.remove('active'));
tab.classList.add('active');
contents[index].classList.add('active');
});
});
See the Pen JavaScript - Tab Menu by Pyxofy (@pyxofy) on CodePen.
まとめ
今回は、JavaScript でタブ切り替えメニューを作る方法を紹介しました。
コードのポイントとなったのが、forEach()
メソッドや for...of
ループを使った反復処理です。見出しとなるすべてのタブにクリックイベントを追加し、タブとそれに対応するコンテンツにクラスの付け外し処理を行うことで、表示が切り替わるようにコーディングしました。
最後まで読んでいただき、ありがとうございます。この記事をシェアしてくれると嬉しいです!
こちらもチェック!LinkedIn・ Threads・ Mastodon・ X (Twitter) @pyxofy・ Facebook