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

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

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

![スクリーンショット 2021-07-11 13.07.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1554142/f37a679d-40c6-db7a-5afe-913d53347069.png)

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

ぼくの[ポートフォリオ](https://oogiri-legendroad.com/)にも実装していますので、実際に確認してみてください。

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

#開発環境

> ruby 2.6.3
> Rails 5.2.6

#前提

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

人気順や今週の〜は過去に記事にしていますのでそちらも参考にしてみてください。
[[Rails]いろんなランキング表示(いいね、コメント、投稿数)
](https://qiita.com/nakachan1994/items/ace3508d5192c58efdf1)
[[Rails]月間、週間、日別でランキング機能を実装(Time.current)](https://qiita.com/nakachan1994/items/682ae620bf3fa6687d5c)

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

user  ユーザー
post  投稿

#手順

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

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

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

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

```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タグで囲っていきます。

```erb: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-active`、`box-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');
    });
  });
});
```

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

こちらの記事で詳しく解説しています。
[[Rails]リロードしないとJavaScript(jQuery)が動かない問題](https://qiita.com/nakachan1994/items/974f1d3c17d43446acb9)


#タブのデザインを整える

ここまでで、タブの切り替え機能は出来ているので、最後にデザインを整えていきます。
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だけでかんたんに実装できました！
少しでも参考になれば幸いです。