当ブログではPRや広告を掲載しています

【Rails】kaminari と jscroll で無限スクロールを一瞬で実装!

rails jscroll infinite scroll プログラミング
この記事はこんな人向け
  • Rails初学者
  • Railsで少しページを作って表示したことがあるレベル
  • 無限スクロール(infinite scroll)を実装したい人
スポンサーリンク

手順

まず初めに、ざっくりとした手順を示しておきます。
無限スクロールを入れる方法は、以下の通りです。

  1. ページング機能を入れる
  2. 無限スクロールのプラグインを入れる
  3. ページングのレイアウトを整える

では解説していきます!

ページング機能の導入

kaminari

kaminari の導入

最初に、ページング機能を入れるために gem を1つ追加します。
その gem は、”kaminari” です。(ページングの代表的なgemですね)

では、Gemfile に以下の記述を追加し、bundle install してください。

Gemfile
gem 'kaminari'

問題なくインストールできたら次にいきます。

一覧画面の編集

無限スクロールを入れるにあたって、ページングを入れますが、その対象ページのコードを修正していきます。

コントローラー(Controller)

まずはコントローラーの記述をします。

今回は Book というモデルを扱って、レコードを取得して表示します。
コントローラーに次のような記述をします。

app/controllers/books_controller.rb
def index
  @books = Book.all.page(params[:page]).per(5)
end

末尾の “per(5)” という記述は、「5レコードごとにページングするよ」という宣言になります。
この数字を変えれば、画面に1回で表示されるレコード数が変わります。

ビュー(View)

次にビュー(フロント)側に以下のように記述をします。

今回はわかりやすく tableタグ を使いますが、お好みに応じて変えてください。

app/views/books/index.html.erb
<table class='table table-hover table-inverse'>
  <thead>
    <tr>
      <th>Title</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <% @books.each do |a_book| %>
    <tr>
      <td><%= link_to a_book.title, book_path(a_book.id) %></td>
      <td><%= a_book.description %></td>
    </tr>
    <% end %>
  </tbody>
</table>
<%= paginate @books %>

最後の paginate の部分でページネーションを実現しています。
これがあることで、以下の画像のようにページングのリンクが生成されます。

paging

ページングはこれで完了です!
次に、本題の無限スクロールにいきましょう。

無限スクロールのプラグインの導入

jscroll の導入

無限スクロールには、「jscroll」という便利なやつを使います。

導入方法としては2つあって、CDN か min.js を入れる方法があります。
両方のやり方を解説するので、どちらか好きな方を使ってください。

CDN での導入方法

CDN では scriptタグ をどこに書くかの問題だけなので、代表的な箇所を2つ紹介しておきます。

application.html.erb もしくは一覧表示する html.erb のファイルに書くのがおすすめです。
※両方ではなく、どちらか一方に記述することに注意してください!

application.html.erb に書いた場合は、その設定がアプリ全体で有効になるので、他のページでも無限スクロールを入れる際に楽チンです。

一覧表示する html.erb に書く場合は、そのページを表示する時にのみプラグインを読み込むので、他のページでは不要なものを読み込まないぶん、画面表示がわずかに早いメリットがあります。

app/views/layouts/application.html.erb
<head>
  ...
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jscroll/2.4.1/jquery.jscroll.min.js"></script>
  ...
</head>

もしくは

app/views/books/index.html.erb
...
#画面表示するタグの後ろ(ファイル末尾)に追加するのがセオリー
<script src="https://cdnjs.cloudflare.com/ajax/libs/jscroll/2.4.1/jquery.jscroll.min.js"></script>

min.js での導入方法

min.js は、jsのファイルを自分のアプリに入れる必要があります。

https://github.com/pklauzinski/jscroll/blob/master/dist/jquery.jscroll.min.js のファイルをダウンロードし、 app/assets/javascripts フォルダに配置します。

そして、上記ファイルを読み込む設定を application.js に記載します。
(デフォルトから記述を変更していない場合は、特に変更いらないカモ?)

app/assets/javascripts/application.js
# 以下のどちらかを追記する。(既にあればOK)
//= require jquery3
//= require jquery

# 上のjqueryよりも下に、以下のどちらかを追記する。
//= require_tree . #これが既にあれば下のは不要。
//= require jquery.jscroll.min.js

jscroll の反映

プラグインの導入は済んだので、ビューを変更してプラグインの機能を反映させていきます。

一覧画面のビューファイルで、特定の divタグ と、jsのコードを以下のように追加します。

app/views/books/index.html.erb
<div class='jscroll-div'> <!-- 追記 -->
  <table class='table table-hover table-inverse'>
    ... <!-- ここは変更なしのため割愛 -->
  </table>
  <%= paginate @books %>
</div>  <!-- 追記 -->

<!-- ファイル末尾に以下を追記(application.jsに書いてもOK) -->
<script>
  $(document).on('turbolinks:load', function() {
    $('.jscroll-div').jscroll({ // 追加したdivのclass名と合わせる
      contentSelector: '.jscroll', 
      nextSelector: '.next a',  // 次ページリンクのセレクタ
      loadingHtml: '読み込み中',
      padding: 10
    });
  });
</script>

たったこれだけで、ひとまずは無限スクロールが動くようになると思います。
以下のような感じで、2ページ目に表示されるはずのレコードが1ページ目と並んで表示されています。

infinite scroll

ただ、とりあえず動きますが、ページングのリンクが見えたままになっているのが気になりますよね。

では最後にページングのリンクを消すことで、見た目を整えましょう。

ページングのリンクを非表示に

ページングのリンクを見えないように(非表示に)するには、cssをいじって見えないようにします。

以下のコードを、先ほどのフロント側のファイル(index.html.erb)か、もしくは application.scss に追記します。
※application.scssに書く場合は、”style”タグは不要なので注意してください!

app/views/books/index.html.erb
<style>
  .pagination {
    visibility: hidden;
  }
</style>

これでページングのリンクが見えなくなってスッキリしました!

pagination visibility hidden

(visibility: none; にすると余白も無くなるため、この方がいいかもしれません。)

まとめ

Rails で kaminari と jscroll を用いた無限スクロールの実装手順を解説しました!

技術的にはjqueryを使って動的に要素を生成している、といった背景はあるのですが、これがjscrollでブラックボックス化されているんですね。
なので、プログラミング歴が浅い方でもわりと簡単に実装できるのが最大のメリットだと思います。

今回は tableタグ でやったため、見た目はイマイチだったかもしれませんが、divタグ で行を構成すれば見た目は整うので、工夫してやってみてください。

コメント

タイトルとURLをコピーしました