原文:http://www.cnblogs.com/aoyo/p/5247621.html
效果就如我的个人站yooao.cc,把我实现的思路分享给大家。
Masonry渲染页面如果有图片时需要imagesLoaded辅助,不然有可能会造成布局重叠。
一个大体的思路:前端取得最后一篇文章的id,下拉时进行Ajax请求添加文章进布局,并同时更新最后一篇文章的id,这样就可往复循环实现无限瀑布流刷新。
下面说说具体的实现:
一、前端
对于Masonry 的基本布局,可以看它的文档。
<a id="add-button" href="<?PHP echo Url::to(['post/site/addpost','type_id'=>$type_id,'last_id' => $last_id]) ?>" class="btn btn-danger">加载更多</a>
因为我用的Yii2框架,所以Yii2提供的方法生成href,生成的href就像这样:http://yooao.cc/index.PHP?r=post/site/addpost&last_id=71
,type_id是对指定类别的文章添加时需要的,last_id就是最后一篇文章的id。
下面是具体的js代码:
$(function(){ var add_href = $('#add-button').attr('href'); var patt = /\d+$/g; var last_id = patt.exec(add_href)[0];//取得last_id的值 $('#add-button').hide(); 如果不想显示这个添加按钮,可以将它隐藏 var add_ajax_count = 0; 定义一个计数器,避免下拉到底时短时间内进行多次Ajax请求 $(window).on('scroll',function(){ 计数器为0并且滚动条离底部小于10px时,才会进行Ajax请求 if( $(document).scrollTop() + $(window).height() > $(document).height() - 10 && add_ajax_count == 0 ) { add_ajax_count++; 请求一次则将计数器+1 $.ajax({ type: "post",url: $('#add-button').attr('href'),dataType: "json",async: true,data: {'last_id' : last_id},0); line-height:1.5!important">提供给控制器last_id beforeSend: function(){ $('#ajax-loader').show(); 加载时显示的图片 },complete: function(){ $('#ajax-loader').hide(); },success: function (posts) { var count_post = posts.length; if(count_post == 0 ){ return false; } 将last_id变更为此次请求的最后一篇文章的id last_id = posts[posts.length-1].id; (function(){ var i = 0; 这里设置每0.9秒添加一个小块。如果不用计时器而用for,我测试结果是会造成重叠。 setInterval(if(i >= count_post){ false; } $elem是每个小块的模版 var $elem = $('<div class="grid-item" >' + posts[i].title + '</div>'); $grid.append($elem); 等图片加载完后才渲染新添加的小块 $elem.imagesLoaded( function() { $grid.masonry('appended',$elem ); }); i++; },900); })() 8是我设置的每次添加的文章数,如果此次得到的文章数小于8说明已经到最后,count_post 的值将会为1,之后再下拉不会触发Ajax请求。 if(count_post < 8 ){ false; }else{ add_ajax_count--; } } }); } }); });
二、后端
用Yii2举例,控制器代码:
public function actionAddpost($type_id=null) { $model = new Post(); $posts = $model->addPost($type_id); return json_encode($posts); }
post模型的addPost方法:
public function addPost($type_id=null) { if($_POST['last_id'] !== null){ $last = $_POST['last_id']; } if($type_id == null){ $posts = Post::find()->where('status = 1 AND id < :id',[':id' => $last])->orderBy('id DESC')->limit(POST::PRE_PAGE_POST)->asArray()->all(); }else{ $posts = Post::find()->where('id < :id AND type_id = :type_id AND status = 1',[':id' => $last,':type_id'=>$type_id])->orderBy('id DESC')->limit(POST::PRE_PAGE_POST)->asArray()->all(); } return $posts; }