読者です 読者をやめる 読者になる 読者になる

【Ruby On Rails】infinit scrollとkaminariによる無限スクロールの実装

javascriptプラグインinfinitscroll.jsとrailsのページネーションプラグイン"kaminari"を使って、いわゆる無限スクロールページを実装します。

環境

$ ruby -v ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-linux] $ rails -v Rails 4.1.8

デモ

作成したデモ。ページの最下部にスクロールすると、新たに部分テンプレートのページが読み込まれるようになっている。

デモ

概要

  1. Gemに必要なプラグインを追加
  2. Pictureモデルを作成
  3. Pictureを複数表示する部分テンプレートを作成
  4. 部分テンプレートごとにページネーションを実装
  5. 無限スクロールを実装

手順

Gemに必要なプラグインを追加

以下のGemを追加

# vi Gemfile
gem 'kaminari'
gem 'jquery-turbolinks'

Pictureモデルを作成

例えば以下のようにPictureモデルを作成する

$ rails generate scaffold Picture title:string img:string
$ rake db:migrate

Pictureを複数表示するよう部分テンプレートを作成

パーシャルを表示する大元のページを作成

# vi app/views/pictures/search.html.erb

<div id="pictures">
  <div class="page">
    <%= render 'search_result' %>
  </div>
</div>

<%= javascript_include_tag 'jquery.infinitescroll' %>

写真を表示するテンプレートとしてパーシャルを作成

# vi app/views/pictures/_search_result.html.erb

<div class="pictures">
      <% @pictures.each do |p| %>
          <img src="p.img" alt="photos">
      <% end %>
</div>

部分テンプレートごとにページネーションを実装

コントローラーを以下のように編集

# vi app/controllers/pictures_controller.rb

def search
  @pictures = Picture.order(:created_at).page(params[:page]).per(30)
end

per(30)で、1ページあたり30件表示させている。(デフォルトは25?)

先ほど作成した部分テンプレートに以下を追記

# vi app/views/pictures/_search_result.html.erb

<%= paginate @pictures %>

試しに/pictures/searchにアクセスすると以下のようにページ番号が表示されている

f:id:watarisein:20160102012502p:plain

無限スクロールを実装

まずは、JavaScriptリクエストのために、部分テンプレートをappendするビューを記載する

# vi app/views/pictures/search.js.erb

$("#pictures").append("<div class='page'><%= escape_javascript(render('search_result', :locals => { :tags => @picture.tag_list })) %></div>");

infinitscroll.jsを読み込んで無限スクロール用の設定 先ほど作成したsearchのビューファイルに以下を追加

# vi app/views/pictures/search.html.erb

<%= javascript_include_tag 'jquery.infinitescroll' %>
<script>
$("#pictures .page").infinitescroll({
    loading: {
      img:     "http://www.mytreedb.com/uploads/mytreedb/loader/ajax_loader_blue_48.gif",
      msgText: "loading..."
    },
    navSelector: "nav.pagination",
    nextSelector: "nav.pagination a[rel=next]",
    itemSelector: "#pictures div.pictures" /* このDOMに差し掛かった時に、次のページのロードが始まる*/
});
</script>

これで無限スクロールが完成

参考

How To: Create Infinite Scrolling with jQuery · kaminari/kaminari Wiki · GitHub

Infinite Scroll | jQuery plugin, Wordpress plugin, interaction design pattern