
こんにちは、未経験からITエンジニアへの転職を目指しているごんにんごんです。
今日はjQueryの「タブ切り替え機能」について、理解を深めるために記載したいと思います。
というのも、現在所属しているTechCampでは、Ruby on Railsを使ったサーバーサイドの演習がメイン(カリキュラム全体の8割強)となっています。そのため、カリキュラムをやり通しても、「あれ?HTML/CSSに触るの、カリキュラムの3日目以来だな…」とか、「JavaScriptって発火くらいしかわかってない」てな感じで、フロントの知識がほぼ身についていないのです(体験談)
今取り組んでいるWebアプリケーションもそうですが、アプリケーションを作る上でフロントの知識も必須のはず。本来ならフロントの専門書を一読してから、進めるべきかもしれませんが、私はこんな▼感じで手を動かしながら身につけようと思います。
- アプリケーションに○○な機能を導入したい、どうやってやるんだろう?
- 類似事例を見つけた!私のアプリケーションだとどうなるだろう?
- アウトプットで内容を知識定着させよう
ということで、jQueryのアウトプットをやっていきたいと思います。
Contents
こんな機能を作った!
冷蔵庫のシェアリングアプリを制作中なんですが、ユーザーに食材を登録してもらう機能を実装しています。
シンプルに作るのであれば、「食材ごとにカテゴリをプルダウンで選んでもらう」方法かなと思いますが、ユーザー視点で考えてみると、、、
- 食材の登録する量は思いのほか有る。登録の度に、プルダウンでカテゴリを選んでもらうのは手間。
- 面倒なステップが一つでもあれば、アプリから離れてしまうので、極力「操作させない」ことがポイント。
だと思ったので、タブで切り替えることにしました。

HTMLファイル
まずはHTMLファイルについて説明します。
構成は以下の通りです。
- “タブエリア”と“コンテンツエリア”として、2つのクラスを用意する。
- デフォルトで表示させるタブ(今回は一番上のタブ)のクラスに、”active”を付与しておく。
- タブと連動させる形で、表示させるコンテンツのクラスに、”show”を付与しておく。
HTMLファイルにごちゃごちゃ書いてますが、5つの「タブクラス」と「コンテンツクラス」が有るんだなぁと思ってください。
“active”と”show”については、この後のCSSファイルで説明します。
<div class="item-contents">
<h2 class="items-sell-title">食材 <i class="fa-solid fa-box-archive"></i> を登録しよう</h2>
<h3>登録する食材のカテゴリを選ぼう!</h3>
<div class="tab-area">
<div class="tab active" id="tab-fish" data-value='1' >
<i class="fa-solid fa-fish fa-2x"></i>Fish
</div>
<div class="tab" id="tab-veg" data-value='2' >
<i class="fa-solid fa-carrot fa-2x"></i>Vegitable
</div>
<div class="tab" id="tab-meat" data-value='3'>
<i class="fa-solid fa-cow fa-2x"></i>Meat
</div>
<div class="tab" id="tab-drink" data-value='4'>
<i class="fa-solid fa-wine-bottle fa-2x"></i>Drink
</div>
<div class="tab" id="tab-flozen" data-value='5'>
<i class="fa-solid fa-ice-cream fa-2x"></i>Flozen
</div>
</div>
<%# <div class="items-sell-main"> %>
<div class="content-area">
<%= form_with model: @form, url: box_foods_path, method: :post, local: true do |form| %>
<%= render 'shared/foods_error_messages', model: @form %>
<%# TODO : フォーム追加できるようにする。https://web-tsuku.life/add-form-appendchild/ %>
<div class="content show">
<%= render partial: 'shared/fields_for', locals:{ form: form, i: 1 } %>
</div>
<div class="content">
<%= render partial: 'shared/fields_for', locals:{ form: form, i: 2 } %>
</div>
<div class="content">
<%= render partial: 'shared/fields_for', locals:{ form: form, i: 3 } %>
</div>
<div class="content">
<%= render partial: 'shared/fields_for', locals:{ form: form, i: 4 } %>
</div>
<div class="content">
<%= render partial: 'shared/fields_for', locals:{ form: form, i: 5 } %>
</div>
<div class="sell-btn-contents">
<%= form.submit "登録する" ,class:"sell-btn", id:"food-btn" %>
<%=link_to 'もどる', root_path, class:"back-btn" %>
</div>
<% end %>
</div>
</div>
JavaScriptファイル
次に肝要のJSファイルについて。実装の流れは、以下の通りです。
- 【タブ】いずれかのタブがクリックされたら発火する。
- 【タブ】クリックされていることを表すために色を変えるクラス(activeクラス)が、タブクラスにくっついているので、全て外す。
- 【タブ】クリックされたタブにactiveクラスを付与する。
- 【共通】何番目のタブがクリックされたか判定する。
- 【コンテンツ】コンテンツを表示させるためのクラス(showクラス)が、コンテンツクラスにくっついているので、全て外す。
- 【コンテンツ】4で判定したタブ・コンテンツに対して、showクラスを付与する。
クリックを起点にして、activeクラスとshowクラスを使って、タブ遷移を実装していますね。どうやって実装しているんでしょうか。CSSを見てみましょう。
const tab = () => {
let tabs = $(".tab"); // tabのクラスを全て取得し、変数tabsに配列で定義
$(".tab").on("click", function() { // tabをクリックしたらイベント発火
$(".active").removeClass("active"); // activeクラスを消す
$(this).addClass("active"); // クリックした箇所にactiveクラスを追加
const index = tabs.index(this); // クリックした箇所がタブの何番目か判定し、定数indexとして定義
$(".content").removeClass("show").eq(index).addClass("show"); // showクラスを消して、contentクラスのindex番目にshowクラスを追加
})
window.addEventListener('DOMContentLoaded',tab)
CSSファイル
CSSファイルは以下のとおりです。
.tab-area {
display: flex;
justify-content: space-around;
background-color: #222e3e;
cursor: pointer;
margin-top: 30px;
.tab {
width: 200px;
height: 60px;
line-height: 30px;
text-align: center;
padding: 10px 0;
color: white;
border-right: 1px solid #50637b;
border-left: 1px solid #222e3e;
}
// activeクラス : 色を変えることで、選択されていることを表す
.tab.active {
background-color: #ccc;
color: #222e3e;
border: none;
}
}
.content-area {
font-size: 30px;
text-align: center;
// contentクラス : display: noneなので、基本的に非表示
.content {
display: none;
}
// showクラス : display: blockとすることで、コンテンツが表示される
.content.show {
margin-top: 50px;
display: block;
}
}
ポイントは、タブエリアとコンテンツエリアでのタブ遷移の実装方法です。
タブエリア(activeクラス)
.tab {
width: 200px;
height: 60px;
line-height: 30px;
text-align: center;
padding: 10px 0;
color: white;
border-right: 1px solid #50637b;
border-left: 1px solid #222e3e;
}
// activeクラス : 色を変えることで、選択されていることを表す
.tab.active {
background-color: #ccc;
color: #222e3e;
border: none;
}
クリックされているタブの色を変えることで表現しています。JavaScriptにて、activeクラスが付与されると、色が変わる(クリックされた)ようになっています。
コンテンツエリア(showクラス)
// contentクラス : display: noneなので、基本的に非表示
.content {
display: none;
}
// showクラス : display: blockとすることで、コンテンツが表示される
.content.show {
margin-top: 50px;
display: block;
}
こちらは、表示・非表示でタブの遷移を表現しています。基本的にコンテンツは、display: noneによって非表示となっています。JavaScriptにて、showクラスが付与されると、display: blockによって表示される仕組みです。
まとめ
ホームページでよく目にするタブは、クリックを起点として「タブ遷移を司るクラスの付け外し」していたのだと理解できました。
タブ機能を実装したことで、ユーザビリティの観点で使いやすくなったと思いますので、ぜひ導入してみてください。