Skip to main content
 首页 » 编程设计

ruby-on-rails之使用 Rails 3 和 Jquery 实现无限滚动

2026年07月28日6Renyi-Fan

我正在尝试在我的项目中实现无限滚动。我正在使用 Railscast #114 Endless Page 的组合和 this .

除了当页面结束时我尝试停止发送请求时出现奇怪的行为之外,一切正常。

到目前为止我已经:

Controller :

def show 
    @title = Photoset.find(params[:id]).name 
    @photos = Photoset.find(params[:id]).photo.paginate(:page => params[:page], :per_page => 20) 
    respond_to do |format| 
      format.js 
      format.html 
    end 
end 

显示.html.erb:

<% content_for :body_class, '' %> 
<%= render 'shared/header' %> 
<div id="photos_container"> 
    <div id="photos_header"> 
    <h2><%= @title %></h2> 
    </div> 
    <%= render :partial => 'photo', :collection => @photos %> 
</div> 
<%= render :partial => 'endless_scroll' %> 

Javascript(通过部分加载):

<script type="text/javascript"> 
(function() { 
  var page = 1, 
  loading = false, 
  finish = false; 
 
  function nearBottomOfPage() { 
    return $(window).scrollTop() > $(document).height() - $(window).height() - 200; 
  } 
 
  function finish() { 
    finish = true; 
  } 
 
  $(window).scroll(function(){ 
    if (loading) { 
      return; 
    } 
 
    if(nearBottomOfPage() && !finish) { 
      loading=true; 
      page++; 
      $.ajax({ 
        url: '/photosets/<%= params[:id] %>?page=' + page, 
        type: 'get', 
        dataType: 'script', 
        success: function() { 
          loading=false; 
        } 
      }); 
    } 
  }); 
}()); 
</script> 

show.js.erb

$("#photos_container").append("<%= escape_javascript(render :partial => 'photo', :collection => @photos) %>"); 
<% if @photos.total_pages == params[:page].to_i() %> 
    page.call 'finish' 
<% end %> 

如您所见,在我的 show.js.erb 上我有一个page.call将 true 分配给 finish多变的。这会停止请求。

有线的事情是它永远不会加载最后一页。当@photos.total_pages == params[:page].to_i()而不是仅仅调用 finish函数并将变量设置为 true ,它也防止 $("#photos_container").append("<%= escape_javascript(render :partial => 'photo', :collection => @photos) %>");从运行。

它将请求发送到 Controller ,运行 SQL 但不附加最后一页。

如果我将条件更改为 @photos.total_pages < params[:page].to_i()它可以工作,但会向不存在的页面发送额外的请求。

如果对我的实现有任何帮助,我将不胜感激。我不确定是否有更合适的(Rails)方法来完成此任务。

请您参考如下方法:

首先,当请求为 xhr 类型时,您可以从部分渲染 html:

def show 
  photoset = Photoset.includes(:photos).find(params[:id]) 
  @title = photoset.name 
  @photos = photoset.photo.paginate(:page => params[:page], :per_page => 20) 
  if request.xhr? 
    render '_photo', :layout => false 
  end 
end 

然后使用ajax调用:

$.ajax({ 
  url: '/photosets/<%= params[:id] %>?page=' + page, 
  type: 'get', 
  dataType: 'script', 
  success: function(response) { 
    $("#photos_container").append(response); 
    if (response == "") { 
      //stop calling endless scroll 
    } 
  });   
});