▶️

【Rails & JavaScript】jQueryを使ったスライドショー実装

2023/07/29に公開

スライドショー作成

ECサイトの新着商品情報をスライドショーにする。

※画像がケーキじゃないですがイメージの動きは以下みたいな感じ。
自動で動くし、クリックでも動かすことができます。

実装準備

以下の通り実装準備をしていく。

JavaScriptの実装準備は以下に記載。
https://zenn.dev/ganmo3/articles/c01ce76c09ae8d

jQueryの導入

yarnを使用し導入。

ターミナル
yarn add jquery

jQueryが使用できるように設定していく。

config/webpack/environment.js
const webpack = require('webpack')
environment.plugins.prepend(
  'Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery',
  })
)

jQueryをimportする。

app/javascript/packs/application.js
import 'jquery'

これでjQueryの使用準備が完了。

slickの導入

以下の通り記載する。

  • head終了タグ直前にslickのCSSを読み込む。
  • body終了タグ直前にslickのJSを読み込む。
app/views/layouts/application.html.erb
 <!DOCTYPE html>
 <html>
   <head>
     <title>NaganoCake</title>
     <meta name="viewport" content="width=device-width,initial-scale=1">
     <%= csrf_meta_tags %>
     <%= csp_meta_tag %>

     <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
     <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
+    <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.css"/>

   </head>
   <body>
     <main>
       <%= render 'layouts/header' %>
       <%= notice %>
     <%= yield %>
     <%= render 'layouts/footer' %>
     </main>
+    <script type="text/javascript" src="//cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.min.js"></script>
   </body>
 </html>

実装

商品の情報を取り出したいため、まずはコントローラに追記。

コントローラ記載

app/controllers/public/homes_controller.rb
class Public::HomesController < ApplicationController
  
  def top
    items = Item.all
+   @new_items = items.sort_by { |item| item.created_at }.reverse.first(4)
    @genres = Genre.all
  end

  def about
  end
  
end

解説

上記のコードでは、items配列をsort_byを使用して、created_atに基づいて降順でソートする。
reverseを使用して降順から昇順に変更し、最後にfirst(4)で最初の4つの商品を取得。こうすることで、@new_itemsにはitems配列の中で新着順で4つの商品が格納される。

HTML

app/views/public/homes/top.html.erb
:
:
<div class="container mt-5" id="container">
  <div class="row">
    <div class="col">
      <div class="mt-5">
        <h3><strong>新着商品</strong></h3>
        <div class="row mt-4">
          <ul class="slider">
            <% @new_items.each do |item| %>
            <li>
              <%= link_to item_path(item) do %>
                <p class="caption mx-2"><%= image_tag item.image, format: 'jpeg', size: '300x200' %></p>
              <% end %>
                <p class="caption"><%= item.name %></p>
                <p class="caption">¥<%= item.with_tax_price.to_s(:delimited) %></p>
            </li>
        <% end %>
          </ul>
        </div>
        <p class="text-center mt-5">
          <%= link_to 'すべての商品を見る', items_path, class: "link" %>
        </p>
      </div>
    </div>
  </div>
</div>

解説

  1. スライドショーコンテナ:<ul class="slider">
    スライド要素を包むコンテナ。

  2. スライド(スライドの要素): <li>
    各商品情報を表示するスライド。今回はeachループで各商品を取り出すようにする。

  3. 商品情報の表示: <%= item.name %>, <%= item.with_tax_price.to_s(:delimited) %>
    各スライド内に表示する商品情報。今回は商品名と価格を表示。

  4. 商品画像の表示: <%= image_tag item.image, format: 'jpeg', size: '300x200' %>
    各スライドに表示する商品画像を表示。<%= link_to item_path(item) do %>で画像にリンクをつける。

CSS

app/assets/stylesheets/public/homes.scss
/* 新着商品スライドショー */
.slider {
  width: 94%;
  margin: 0 auto; /* スライドショーを水平方向に中央に配置 */
}

.slider img {
  width: 300px;
  height: 200px;
}

.slider .slick-slide {
  transform: scale(0.8); /* スライドを0.8倍に縮小 */
  transition: all 0.5s; /* スライドの切り替えアニメーション。0.5秒に指定。 */
  opacity: 0.5; /* スライドの透明度を0.5に設定 */
}

.slider .slick-slide.slick-center {
  transform: scale(1); /* 中央にきたメインスライドが通常サイズに拡大 */
  opacity: 1; /* スライドの透明度を1に設定し透明じゃなくする */
}


/* 新着商品リスト装飾 */
/* 各スライドの背景色を設定し、余白と角丸を追加して装飾する */
.slider li {
  background-color: #FFE3E1;
  padding: 10px; /* スライドの内側の余白を追加 */
  border-radius: 10px; /* スライドの角を丸くします */
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); /* スライドに影を追加して立体感を出す */
  text-align: center; /* スライド内のテキストを中央揃えにします */
}

/* 各スライド内の段落要素(<p>タグ)の上下の余白を追加 */
.slider li p {
  margin: 5px 0;
}

/* スライド内の見出し(<p class="caption">タグ)のスタイルを設定 */
.slider li p.caption {
  font-family: 'Sawarabi Mincho', sans-serif;
  font-size: 16px;
  color: #FF1493;
  font-weight: bold;
}

/* 前へボタンと次へボタンのスタイルを設定 */
.slick-prev,
.slick-next {
  position: absolute; /* ボタンをスライド内に絶対位置で配置 */
  top: 42%; /* ボタンを垂直方向に中央に配置 */
  cursor: pointer; /* マウスカーソルをポインターに変更 */
  outline: none; /* ボタンにフォーカスしたときの枠を非表示にする */
  border-top: 2px solid #666;
  border-right: 2px solid #666;
  height: 15px;
  width: 15px;
}

/* 前へボタンのスタイルを設定 */
.slick-prev {
  left: -1.5%; /* ボタンを水平方向にスライドの外側に配置 */
  transform: rotate(-135deg); /* ボタンを反時計回りに45度回転させて矢印の形状にする */
}

/* 次へボタンのスタイルを設定 */
.slick-next {
  right: -1.5%; /* ボタンを水平方向にスライドの外側に配置 */
  transform: rotate(45deg); /* ボタンを時計回りに45度回転させて矢印の形状にする */
}

/* スライドの下部に表示されるドット(ページネーション)のスタイルを設定 */
.slick-dots {
  text-align: center;
  margin: 20px 0 0 0;
}

/* ドットのリスト項目のスタイルを設定 */
.slick-dots li {
  display: inline-block;
  margin: 0 5px;
}

/* ドット(ボタン)のスタイルを設定 */
.slick-dots button {
  color: transparent; /* ドットのテキストを透明にして非表示にする */
  width: 12px;
  height: 12px;
  display: block;
  border-radius: 50%;
  background: #FFC0CB; /* ドットの背景色を薄いピンクに設定 */
  border: none;
}

/* アクティブなドットのスタイルを設定 */
.slick-dots .slick-active button {
  background: #FF1493; /* アクティブなドットの背景色を濃いピンクに設定 */
}

解説

以下の通り解説する。
/ 新着商品スライドショー */部*の実装により以下の通りとなる。

  • 画面水平方向の中央に配置。
  • 中央のアクティブなスライドが通常サイズで不透明に表示。
  • 他の非アクティブなスライドは0.8倍サイズで0.5の透明度で表示。
  • スライドのアニメーションは0.5秒で切り替わるようにする。

/ 新着商品リスト装飾 */部*の実装により、各スライドの背景色や余白を整え、スライドショーがきれいに見えるように装飾している。また、前へ・次へボタンやページネーションのスタイルも設定することでスライドショーの操作性をよくする。

JavaScript

javascript
$(document).ready(function() {
   // スライドショーの設定を記述します
  $('.slider').slick({
    autoplay: true, // 自動再生を有効にする
    infinite: true, // スライドを無限ループさせる
    speed: 500, // スライドの切り替わる速度を0.5秒に指定(ミリ秒単位)
    slidesToShow: 3, // 一度に表示するスライドの数を3枚に指定
    slidesToScroll: 1, // 一度にスクロールするスライドの数を1枚に指定
    prevArrow: '<div class="slick-prev"></div>', // 前へボタンのHTMLコードを指定
    nextArrow: '<div class="slick-next"></div>', // 次へボタンのHTMLコードを指定
    centerMode: true, // センターモードを有効
    variableWidth: true, // 変数幅を有効
    dots: true, // ドット(ページネーション)を表示
  });

解説

以下の通り補足する。

  • センターモード(centerMode: true):
    センターモードは、スライドを中央に配置する機能。centerModetrue に設定することで、スライダーの中央に表示されるスライドが通常のサイズで、周りのスライドは縮小されるため、中央のスライドに焦点が当てられる。

  • 変数幅(variableWidth: true):
    変数幅は、スライドの幅を自動的に調整する機能。設定することでスライドごとに異なる幅を設定できるようになる。

JavaScriptコードの実装により、スライドが自動再生を繰り返していく。もちろん前へ・次へボタンをクリックすればマニュアル操作も可能。


動きが入るとサイトがそれっぽくなる!
使わないと覚えないので積極的につかって実装を覚えていきたい。

Discussion