效果就如個人我的站yooao.cc,把我實現的思路分享給你們。php
Masonry渲染頁面若是有圖片時須要imagesLoaded輔助,否則有可能會形成佈局重疊。前端
一個大致的思路:前端取得最後一篇文章的id,下拉時進行Ajax請求添加文章進佈局,並同時更新最後一篇文章的id,這樣就可往復循環實現無限瀑布流刷新。
ajax
下面說說具體的實現:
json
1、前端後端
對於Masonry 的基本佈局,能夠看它的文檔。
app
在頁面第一次渲染時,我在容器底部設計一個添加按鈕:框架
<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=71async
,type_id是對指定類別的文章添加時須要的,last_id就是最後一篇文章的id。ide
下面是具體的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}, //提供給控制器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(function(){ if(i >= count_post){ return 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 ){ return false; }else{ add_ajax_count--; } } }); } }); });
2、後端
用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; }