Rails中最方便实现的瀑布流滚动加载(Rails infinite scrolling on easy way)

随着现代浏览器性能的提升,前端工程师设计出的交互方式也多种多样。其中瀑布流方式滚动更新加载已经是一种常见的Web前端交互方式了。

然而在Rails中如何实现这样一种随着用户滚动页面就能自动追加内容到页面的方式呢?

有一些现成的Gem可以推荐,例如jquery-infinite-pageswill_paginate_infinite等。不过我觉得它们使用比较复杂,不如自己去实现一个。

本文既然提到最方便,自然是需要用一种最小化改动的方式来实现这样的功能。

具体如何实现,请往下看。

首先假设我们要实现瀑布流式动态更新的对象是Post(或者是Article、News或者其他),第一步我们需要在Gemfile中加入以下两个Gem:

1
2
gem 'will_paginate'
gem 'bootstrap-will_paginate'

然后执行bundle,接着去修改posts_controller.rb,修改其中的index方法:

1
2
3
4
5
6
7
8
def index
@posts = Post.all.paginate(:page => params[:page], :per_page => 10)

respond_to do |format|
format.html
format.js
end
end

这里由于我们增加了js的渲染格式,所以要去views/posts中添加一个index.js.erb模板文件,内容如下:

1
2
3
4
5
6
7
$('#posts_list').append('<%= j render @posts %>');
<% if @posts.next_page %>
$('.pagination').replaceWith('<%= j will_paginate @posts %>');
<% else %>
$(window).off('scroll');
$('.pagination').remove();
<% end %>

上面的代码通过js定位页面中的posts_list作为要追加元素的目标,所以我们稍微修改一下views/posts/index.html.erb,在其中加入posts_list元素:

1
2
3
4
5
6
7
8

<div id="posts_list">
<%= render @posts %>
</div>

<div id="infinite-scrolling">
<%= will_paginate %>
</div>

在这段代码中,我们将@posts集合交给其他模板去渲染了,而这里暂时还没有用来渲染@posts的模板,所以要在views/posts中创建一个_post.html.erb模板文件,内容如下:

1
2
3
4
5
<div>
<h3><%= post.title %></h3>
<p><%= post.content %></p>
<hr/>
</div>

就这么简单,用来输出标题和内容。

最后关键的一步,需要创建一个事件监听器来捕获页面的滚动变化,所以在assets/javascripts/posts.coffee中,加入以下代码:

1
2
3
4
5
6
7
8
9

$(document).on "turbolinks:load", ->
$(window).on 'scroll', ->
more_posts_url = $('.pagination .next_page a').attr('href')
if more_posts_url && $(window).scrollTop() > $(document).height() - $(window).height() - 60
$('.pagination').html('<img src="/assets/ajax-loader.gif" alt="Loading..." title="Loading..." />')
$.getScript more_posts_url
return
return

如此一来,就实现了通过ajax方式请求原来需要在下一页展现内容,并把内容追加到index.html的文章列表中,也就实现了瀑布流加载了。

一切修改好以后,重启Rails服务,在页面滚动一下试试吧。

本方法参考自https://www.sitepoint.com/infinite-scrolling-rails-basics/

CentOS6安装sassc(Install sassc gem on CentOS 6) 颠覆者的困局


댓글

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×