73
74

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

kaminari + jscrollを使った無限スクロールの実装

Last updated at Posted at 2019-02-23

はじめに

Railsで無限スクロールを実装してみたので、その備忘録的に投稿しようと思います。

kaminariというページネーションを簡単に実装できるgemを使い、無限スクロールを実装してみたいと思います。
無限スクロールにはjscrollというjQueryのライブラリを使います。

無限スクロールとは

無限スクロールはメルカリの商品一覧でも見る、下までスクロールすると新しい商品が自動的に読み込まれるあれです。

無限スクロールにはページネーションを先に実装する必要があります。
ページネーションにはkaminariというgemを使います。

Railsのバージョンは5です。

kaminariのインストール

Gemfile
gem 'kaminari'

を記載して、

bundle install

を実行するだけです。

jscrollのインストール

jscrollには現時点では(2019年2月)gemが存在しないと思われますので、公式のページからダウンロードしてきます。

なお、jscrollを使うにはjQueryが必要です。
railsでjQueryを使えるようにするにはこちら

jscroll公式ページ

  • CDNで使えるようにする

手軽に試してみたい人はこちら。

<script src="https://cdnjs.cloudflare.com/ajax/libs/jscroll/2.4.1/jquery.jscroll.min.js"></script>
  • ローカルに落とす

こちらのdistからjquery.jscroll.min.jsをダウンロードしてきます。
jscrollのGithub

そして、asset/javascripts配下にダウンロードしたjquery.jscroll.min.jsを置いて、(読み込めれば場所はどこでも)

assets/javascripts/application.js
//= require jquery.jscroll.min.js

を記載。

ページネーションを実装

今回はDBに登録してあったプログラミング言語を一覧で表示するだけの画面を作っていきたいと思います。

skillsというcontrollerを作成し、以下を記載。

skills_controller.rb
class SkillsController < ApplicationController
  def index
    @skills = Skill.page(params[:page]).per(10)
  end
end

.page(params[:page]).per(10)の部分が一画面に10個の要素を表示するということになります。

そして、index.html.erbに

index.html.erb
<ul class="skill-list jscroll">
  <% @skills.each do |skill| %>
    <li><%= skill.skill_name %></li>
  <% end %>
  <%= paginate @skills %>
</ul>

<%= paginate @skills %>の部分がページの部分。

以上を記載すると、ページネーションが実装できます。とても簡単ですね。
以下のような画面になりました。

pagination.png

無限スクロールを実装

無限スクロールは以下のようにして実装できます。
以下のソースは画面を開いた段階で、次の要素が読み込まれる実装になります。

coffeescript

skills.coffee
$ ->
  $('.jscroll').jscroll
  return

jQuery

$(function() {
  $('.jscroll').jscroll;
});

ただ、これだけだと動きません・・・。次のページへのリンクを指定する必要があるためです。
このようにすると、画面を読み込むと自動的に次のページが読み込まれます。

coffeescript

skills.coffee
$ ->
  $('.jscroll').jscroll
    nextSelector: 'span.next a'
  return

jQuery

$(function() {
  $('.jscroll').jscroll({
    nextSelector: 'span.next a'
  });
});

次のリンクを指定するにはnextSelectorを指定してやります。
ただ、ここれだけでは変な感じで読みこまれると思います。

pagination.png

読み込まれている場所はずれているし、jsのconsoleを見ると、rails-ujsが既に読み込まれていますよ、みたいなエラーが出ていると思います。

これは、次のページのhtmlを全て読み込んでしまっていて、javascriptなども重複して読み込んでしまっているのでエラーが出ています。

なので、次のページの読み込む要素を指定してやって、その要素だけ読み込ませるようにします。

coffeescript

skills.coffee
$ ->
  $('.jscroll').jscroll
    contentSelector: '.skill-list'
    nextSelector: 'span.next:last a'
  return

jQuery

$(function() {
  $('.jscroll').jscroll({
    contentSelector: '.skill-list',
    nextSelector: 'span.next:last a'
  });
});

次にロードする要素として、ulの.skill-listを指定しています。

nextSelectorでspan.next:last aで:lastを指定しているのは、
読み込むリンクはhtmlを読み込んでいくとどんどん増えていきます。

なので、読み込まれた最後のリンクを指定してやることで、どんどん次のページを読み込むようにしています。

ulはpaddingが入ることを忘れていたので、

skills.scss
ul.skill-list {
  padding: 0;
}

を記載。すると、以下のように。
pagination.png

あとはページの部分が邪魔なので、

skills.scss
nav.pagination {
  display: none;
}

でページ部分を表示させないようにする。

最終的な画面

Loadingしている時、
pagination.png

Loading後
pagination.png

後は、画面下までスクロールしたことをjavascriptで検知させて、$('.jscroll').jscrollを呼び出してやれば次の要素を読み込めます。

画面下までスクロールしたことを判定

こちらの記事を参考にさせて頂きました。

coffeescript

$(window).on 'scroll', ->
  scrollHeight = $(document).height()
  scrollPosition = $(window).height() + $(window).scrollTop()
  if (scrollHeight - scrollPosition) / scrollHeight <= 0.05
    # スクロールの位置が下部5%の範囲に来た場合
    $('.jscroll').jscroll
      contentSelector: '.skill-list'
      nextSelector: 'span.next:last a'
    return
  return

jQuery

$(window).on('scroll', function() {
	scrollHeight = $(document).height();
	scrollPosition = $(window).height() + $(window).scrollTop();
	if ( (scrollHeight - scrollPosition) / scrollHeight <= 0.05) {
          $('.jscroll').jscroll({
            contentSelector: '.skill-list',
            nextSelector: 'span.next:last a'
          });
	}
});

これで、画面下までスクロールしたら自動的に、次の要素が読み込まれるようになります。

おわりに

ライブラリなどを使うと非常に簡単に無限スクロールが実装できます。

結構モダンなページがお手軽にできると思いますので、是非お試しあれ。

73
74
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
73
74

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?