Masonry + Ajax 實現無限刷新瀑布流

原文: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},  //提供給控制器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--;  
                }
               }                  
        });         
    }
});


});
複製代碼

 

 

 

二、後端

用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;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章