【Rails】slickを用いた画像スライダーの実装


はじめに

railsでアプリケーションに画像スライダーを実装する方法を記述します。
slickを用いた導入方法簡単な実装のみの記述です。
詳しい内容は公式ページを参照してください。(http://kenwheeler.github.io/slick/)
また、初回ページ読み込みかリロードでは正常に作動しますが、ページ遷移して該当ページに戻ってくると動かないという問題にはまって苦戦しましたので、まとめて共有致します。
解釈が正しくない箇所や、もっと上手くできる箇所などがある場合はご指摘いただけると助かります。

railsの学習を始めて3ヶ月の素人による拙い記事ですが、同じくエンジニアを志す初学者の方々の助けになればと思います。

環境

  • Ruby 2.5.7
  • Rails 5.2.5

1. 準備

slickはjQueryプラグインの為、jQueryをインストールします。

Gemfile
gem "jquery-rails"

記述したら忘れずにbundle installします。
jsファイルに以下を追記します。

assets/javascripts/application.js
//= require jquery
//= require rails-ujs

準備は以上になります。

2. slickの導入

まずは公式サイトから必要ファイルをダウンロードします。
下の方までスクロールしていくと以下のようなダウンロードリンクがあります。

ダウンロードしたファイルから以下の3つのファイルを下記のディレクトリに格納します。

slick.min.js
slick.scss
slick-theme.scss

ファイル 格納場所
slick.min.js app/assets/javascripts/
slick.scss app/assets/stylesheets/
slick-theme.scss app/assets/stylesheets/

ファイルを格納したらapplication.html.erbに必要な記述をします。

app/views/layouts/application.html.erb
  <head>
    <title>Title</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>

    <!--この2行を追加-->
    <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/[email protected]/slick/slick.css"/>
    <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/[email protected]/slick/slick-theme.css"/>
  <!--ここまで-->

    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>

  </head>

書き方は先ほどファイルをダウンロードした公式サイトのダウンロードリンクの下にあります。

3. 実装

準備、導入ができましたら、実装に移ります。
画像スライダーを実装したいhtmlファイルに記述していきます。
例えば、postsテーブルのimageカラムの画像をeachで並べると以下のような記述になります。

html.erb
<div class="slider">
  <% @posts.each do |post| %>
    <%= attachment_image_tag post, :image, :fill, 1200, 800, format: "jpeg" %>
   <% end %>
</div>

次にCSSファイルに、スライドのボタン位置を調整するなどの記述をしていきます。
あくまで一例です。

application.css
.slider { padding: 0;}
.slider img { width: 100%;}
.slider div { margin: 0 5px;}
.slider .slick-next { right: 17px; z-index: 100;}
.slider .slick-prev { left: 23px; z-index: 100;}

次にjsファイルに、動き方などの詳しい内容を設定する記述をしていきます。

assets/javascripts/application.js
$(document).ready(function(){
  $('.slider').slick({
    autoplay: true, //自動再生
    infinite: true, //スライドのループ有効化
    dots: true, //ドットのナビゲーションを表示
    slidesToShow: 4, //表示するスライドの数
    slidesToScroll: 4, //スクロールで切り替わるスライドの数
    responsive: [{
      breakpoint: 768, //ブレークポイントが768px
      settings: {
        slidesToShow: 3, //表示するスライドの数
        slidesToScroll: 3, //スクロールで切り替わるスライドの数
      }
    }, {
      breakpoint: 480, //ブレークポイントが480px
      settings: {
        slidesToShow: 2, //表示するスライドの数
        slidesToScroll: 2, //スクロールで切り替わるスライドの数
      }
    }]
  });
});

スマートフォンだと画像が小さくなりすぎる為レスポンシブにします。ブレークポイントは768pxと480pxで指定しています。
ここでは全て紹介出来ませんが、痒い所に手が届く細かい設定も色々できますので、是非調べてみて下さい。
実装は以上になります。

ページ遷移での挙動の乱れ

私がなかなか原因を特定できず苦戦した問題が、ヘッダーからのページ遷移でslickが機能しなくなるというものです。
結論から言うと原因は以下でした。
「デフォルトgemであるturbolinks(ajaxとajaxとhistoryAPIを使ってページ遷移しやすくするもの)が動作しているため、$(document).ready()が動かない」

turbolinksとは?

何かリンクをクリックした時にページ全体を読み込むのではなくheadの一部とbodyの中だけを書き換え、読み込みの高速化をしてくれる機能

この為、新しいページが読み込まれてるように見えますが実は同じページのままになっているのでJavaScriptが動かない、ということらしいです。

解決策

Gemfileへの記述を削除しTurbolinksを無効にするなど、解決方法は様々あるようですが、個人的に良いなと思った解決策が以下になります。

assets/javascripts/application.js
$(document).on ("turbolinks:load", function(){
(以下略)

jsファイルの最初の記述を上記の通り変更すると「turbolinks:load」の記述によってページ遷移時でも正常に動くようになるそうです。

まだまだ勉強中の身の為、コメントやご指摘を頂けると非常にありがたいです。

参考にした記事

【jQuery】カルーセルスライダーslickの使い方とサンプル集
https://www.jungleocean.com/programming/190201jquery-slick

【Rails】ページを更新しないとJavaScriptが動かない時の対処法
https://pote-chil.com/rails_javascript_turbolinks/

slickについて分かりやすくまとめて下さっている投稿

Railsでslickを用いてスライドショーを実装する方法(一枚ずつ & 複数枚ずつ)
https://qiita.com/Yusuke_Hoirta/items/309bac88a4f75b58128b

【Rails】slick(スライダー機能)を簡単に導入する方法
https://qiita.com/rised/items/fff7dd86728a21694a29