LoginSignup
8
13

More than 1 year has passed since last update.

[Rails]CSSとJavaScriptを使ったタブ切り替え機能

Posted at

今回は、CSSとJavaScriptを使って、動きのあるタブ機能の実装をしていきます。

完成イメージはこちらです。

スクリーンショット 2021-07-11 13.07.12.png

選択中のタブは水色になっていて、カーソルが乗ったらちょっと浮くような仕様にしています。

ぼくのポートフォリオにも実装していますので、実際に確認してみてください。

それではいってみましょう!

開発環境

ruby 2.6.3
Rails 5.2.6

前提

  • 投稿サイトを想定
  • New(新着順)
  • Popular(人気順)
  • Pick up(今週のおすすめ)

人気順や今週の〜は過去に記事にしていますのでそちらも参考にしてみてください。
[Rails]いろんなランキング表示(いいね、コメント、投稿数)

[Rails]月間、週間、日別でランキング機能を実装(Time.current)

モデル名、変数名等は適宜、ご自身の開発環境に変換してお考えください。

user ユーザー
post 投稿

手順

タブ切り替え機能を実装する手順は、4ステップです!

  • タブで切り替える範囲を部分テンプレート化する
  • タブ部分の準備をする
  • タブ切り替えの処理を記述
  • タブのデザインを整える

タブで切り替える範囲を部分テンプレート化する

まずは、タブで切り替えしたい範囲を部分テンプレート化します。(今回は_list.html.erb)
表示する値は部分テンプレートに渡す変数でを変えます。

views/posts/_list.html.erb
<% posts.each do |post| %>
  <%= link_to post_path(post.id) do %>
    <%= attachment_image_tag post, :image, :fill, 200, 200 %>
  <% end %>
  <p>説明:<%= post.content %></p>
  <p>ユーザー名:<%= post.user.name %></p>
  <p><%= link_to "#{post.comments.count} コメント", post_path(post.id) %></p>
<% end %>

タブ部分の準備をする

準備として、タブの表示部分と、部分テンプレート化した部分をdivタグで囲っていきます。

views/posts/index.html.erb
<!--タブ部分-->
<ul class="tab-list list-unstyled">
  <li class="tab tab-active">
    New
  </li>
  <li class="tab">
    Popular
  </li>
  <li class="tab">
    Pick up
  </li>
</ul>
<!--タブで選択された要素部分-->
<div class="tabbox-contents">
  <div class="tabbox box-show">
    <%= render 'posts/list', posts: @new_posts %>    
  </div>
  <div class="tabbox">
    <%= render 'posts/list', posts: @popular_posts %>
  </div>
  <div class="tabbox">
    <%= render 'posts/list', posts: @pick_up_posts %>
  </div>
</div>

listの・は非表示にしています。

ポイントとしては、tab-listのtab-active、tabbox-contentsのbox-showで、今どのタブが選択されているかを判断するので、必ずつけておいてください。
また、tab-activebox-showをつけた要素がページ遷移時に選択されている状態になります。

タブ切り替えの処理を記述

準備が出来たので、実際にタブ切り替えの処理を記述していきます。

assets/javascripts/application.js
// タブの切り替え
$(document).on('turbolinks:load', function() {
  $(function() {
    $('.tab').click(function(){
      $('.tab-active').removeClass('tab-active');
      $(this).addClass('tab-active');
      $('.box-show').removeClass('box-show');
      const index = $(this).index();
      $('.tabbox').eq(index).addClass('box-show');
    });
  });
});

tabがクリックされたら、今あるtab-activeを削除して、クリックされたtabにtab-activeを追加して、タブを切り替えています。

assets/javascripts/application.js
// turbolinksの無効化
$(document).on('turbolinks:load', function() {
  $(function() {
    // .tabがクリックされたときを指定
    $('.tab').click(function(){
      // 今ある.tab-activeを削除
      $('.tab-active').removeClass('tab-active');
      // クリックされた.tabに.tab-activeを追加
      $(this).addClass('tab-active');
      // 今ある.box-showを削除
      $('.box-show').removeClass('box-show');
      // indexに.tabのindex番号を代入
      const index = $(this).index();
      // .tabboxとindexの番号が同じ要素に.box-showを追加
      $('.tabbox').eq(index).addClass('box-show');
    });
  });
});

1行目の$(document).on('turbolinks:load', function()をつけないと、うまく動作しません。

こちらの記事で詳しく解説しています。
[Rails]リロードしないとJavaScript(jQuery)が動かない問題

タブのデザインを整える

ここまでで、タブの切り替え機能は出来ているので、最後にデザインを整えていきます。
CSSは見てもらえるとだいたいわかると思うので、解説は省略します。
好みに合わせてデザインはカスタマイズしてみてください。

assets/stylesheets/application.scss
// タブ切り替え
.tab {
  width: 100%;
  padding: 10px;
  cursor: pointer;
  border-left: solid 1px #CCC;
  border-bottom: solid 1px #CCC;
}
.tab:first-child {
  border-left: none;
}
// タブがactiveのときのデザイン
.tab-active {
  color: #FFF;
  background: #19b5d1;
  transition: all 0.2s ease-in-out;
}
// タブの中身、最初は非表示
.tabbox {
  display: none;
  padding: 15px;
}
// box-showクラスのものだけ表示
.box-show {
  display: block;
}
// hover時のアクション
.tab:hover{
  box-shadow: 0 4px 7px 0 rgba(0, 0, 0, 0.5);
  transform: translateY(-1px);
}

まとめ

タブ切り替え機能を実装する手順は、4ステップ

  • タブで切り替える範囲を部分テンプレート化する
  • タブ部分の準備をする
  • タブ切り替えの処理を記述
  • タブのデザインを整える

CSSとJavaScriptだけでかんたんに実装できました!
少しでも参考になれば幸いです。

8
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
13