js實現『加載更多』功能實例


DEMO : 滾動加載示例

關於如何實現『加載更多』功能,網上有插件可用,例如比較著名的使用iscroll.js實現的上拉加載更多、下拉刷新功能。

但實際用起來卻是很麻煩。由於是第三方插件,要按照對方定義的方法使用,用起來總感覺很不順心。再加上iscroll.js本身並沒有集成加載更多的功能,需要進行自行擴展。想繼續使用iscroll.js實現加載更多功能的,上面給的鏈接可以看看。

h5項目里需要實現簡單的分頁功能,由於是移動端,考慮用『加載更多』會更好,而不是PC端的翻頁。

基於按鈕實現加載更多

最簡單的就是給一個加載更多的按鈕,如果還有數據,點擊下加載更多,繼續拉幾條數據;直到沒有更多數據了,隱藏加載更多按鈕。

DEMO : 基於按鈕實現加載更多

這里提前准備好數據。
演示數據格式:blog.json

{
    "list": [
        {
            "title": "這是title",
            "url": "http://www.cnblogs.com/52fhy/p/5271447.html",
            "desc": "摘要"
        },
        {
            "title": "這是title2",
            "url": "http://www.cnblogs.com/52fhy/p/4823390.html",
            "desc": "摘要"
        }]
}

頁面html:

<div class="content">
    <div class="weui_panel weui_panel_access">
        <div class="weui_panel_hd">文章列表</div>
        <div class="weui_panel_bd js-blog-list">
           
        </div>
    </div>
	
	<!--加載更多按鈕-->
	<div class="js-load-more">加載更多</div>
	
</div>
<script src="js/zepto.min.js"></script>

加載更多按鈕樣式:loadmore.css:

@charset "utf-8";

.js-load-more{
	padding:0 15px;
	width:120px;
	height:30px;
	background-color:#D31733;
	color:#fff;
	line-height:30px;
	text-align:center;
	border-radius:5px;
	margin:20px auto;
	border:0 none;
	font-size:16px;
	display:none;/*默認不顯示,ajax調用成功后才決定顯示與否*/
}

加載更多的js代碼:

$(function(){

	/*初始化*/
	var counter = 0; /*計數器*/
	var pageStart = 0; /*offset*/
	var pageSize = 4; /*size*/
	
	/*首次加載*/
	getData(pageStart, pageSize);
	
	/*監聽加載更多*/
	$(document).on('click', '.js-load-more', function(){
		counter ++;
		pageStart = counter * pageSize;
		
		getData(pageStart, pageSize);
	});
});

這里的代碼並不多。其中getData(pageStart, pageSize)是業務邏輯代碼,負責從服務端拉去數據。這里給個示例:

function getData(offset,size){
    $.ajax({
    	type: 'GET',
    	url: 'json/blog.json',
    	dataType: 'json',
    	success: function(reponse){
    
    		var data = reponse.list;
    		var sum = reponse.list.length;
    
    		var result = '';
    		
    		/****業務邏輯塊:實現拼接html內容並append到頁面*********/
    		
    		//console.log(offset , size, sum);
    		
    		/*如果剩下的記錄數不夠分頁,就讓分頁數取剩下的記錄數
    		* 例如分頁數是5,只剩2條,則只取2條
    		*
    		* 實際MySQL查詢時不寫這個不會有問題
    		*/
    		if(sum - offset < size ){
    			size = sum - offset;
    		}
    		
    		/*使用for循環模擬SQL里的limit(offset,size)*/
    		for(var i=offset; i< (offset+size); i++){
    			result +='<div class="weui_media_box weui_media_text">'+
    					'<a href="'+ data[i].url +'" target="_blank"><h4 class="weui_media_title">'+ data[i].title +'</h4></a>'+
    					'<p class="weui_media_desc">'+ data[i].desc +'</p>'+
    				'</div>';
    		}
    
    		$('.js-blog-list').append(result);
    		
    		/*******************************************/
    
            /*隱藏more按鈕*/
            if ( (offset + size) >= sum){
            	$(".js-load-more").hide();
            }else{
            	$(".js-load-more").show();
            }
    	},
    	error: function(xhr, type){
    		alert('Ajax error!');
    	}
    });
}

還是比較簡單的。

基於滾動事件實現加載更多

上面我們通過按鈕點擊實現加載更多,整體過程還是比較簡單的。這里,我提供另一種方法實現加載更多:基於於滾動(scroll)事件。

DEMO : 基於滾動事件實現加載更多

直接貼代碼了:

$(function(){

	/*初始化*/
	var counter = 0; /*計數器*/
	var pageStart = 0; /*offset*/
	var pageSize = 7; /*size*/
	var isEnd = false;/*結束標志*/
	
	/*首次加載*/
	getData(pageStart, pageSize);
	
	/*監聽加載更多*/	
	$(window).scroll(function(){
		if(isEnd == true){
			return;
		}

		// 當滾動到最底部以上100像素時, 加載新內容
		// 核心代碼
		if ($(document).height() - $(this).scrollTop() - $(this).height()<100){
			counter ++;
			pageStart = counter * pageSize;
			
			getData(pageStart, pageSize);
		}
	});
});

可以看出,代碼變化不大,主要看核心代碼里的判斷條件:當滾動到最底部以上100像素時, 加載新內容

業務邏輯getData(pageStart, pageSize)只需要把if ( (offset + size) >= sum)里面的邏輯改成:

if ( (offset + size) >= sum){
	isEnd = true;//沒有更多了
}

就行了。

當然,這里面還有要優化的地方,例如:
如何防止滾動過快,服務端沒來得及響應造成多次請求?

綜合實例

通過上面的例子,顯然第二種更好,不用去點擊。但是第二個方法有個問題:
如果設置頁面大小每次顯示2條或3條(size=2),總記錄是20,你會發現無法觸發向下滾動加載更多的邏輯。這時候有個加載更多的點擊按鈕就好了。

因此,我們可以把以上兩種方法合在一起:
默認使用滾動事件實現加載更多,當顯示數目太小不足以觸發向下滾動加載更多的邏輯時,使用加載更多點擊事件。

DEMO : 綜合實例

這里,我對加載更多這個行為進行簡單的抽象,寫了個簡單的插件:
loadmore.js

/*
 * loadmore.js
 * 加載更多
 *
 * @time 2016-4-18 17:40:25
 * @author 飛鴻影~
 * @email jiancaigege@163.com
 * 可以傳的參數默認有:size,scroll 可以自定義
 * */

;(function(w,$){
	
	var loadmore = { 
		/*單頁加載更多 通用方法
		 * 
		 * @param callback 回調方法
		 * @param config 自定義參數
		 * */
		get : function(callback, config){
			var config = config ? config : {}; /*防止未傳參數報錯*/

			var counter = 0; /*計數器*/
			var pageStart = 0;
			var pageSize = config.size ? config.size : 10;

			/*默認通過點擊加載更多*/
			$(document).on('click', '.js-load-more', function(){
				counter ++;
				pageStart = counter * pageSize;
				
				callback && callback(config, pageStart, pageSize);
			});
			
			/*通過自動監聽滾動事件加載更多,可選支持*/
			config.isEnd = false; /*結束標志*/
			config.isAjax = false; /*防止滾動過快,服務端沒來得及響應造成多次請求*/
			$(window).scroll(function(){
				
				/*是否開啟滾動加載*/
				if(!config.scroll){
					return;
				}
				
				/*滾動加載時如果已經沒有更多的數據了、正在發生請求時,不能繼續進行*/
				if(config.isEnd == true || config.isAjax == true){
					return;
				}
				
				/*當滾動到最底部以上100像素時, 加載新內容*/
				if ($(document).height() - $(this).scrollTop() - $(this).height()<100){
					counter ++;
					pageStart = counter * pageSize;
					
					callback && callback(config, pageStart, pageSize);
				}
			});

			/*第一次自動加載*/
			callback && callback(config, pageStart, pageSize);
		},
			
	}

	$.loadmore = loadmore;
})(window, window.jQuery || window.Zepto);

如何使用呢?很簡單:

$.loadmore.get(getData, {
    scroll: true,  //默認是false,是否支持滾動加載
    size:7,  //默認是10
    flag: 1, //自定義參數,可選,示例里沒有用到
});

第一個參數是回調函數,即我們的業務邏輯。我把最終修改過的業務邏輯方法貼出來:

function getData(config, offset,size){

	config.isAjax = true;

	$.ajax({
		type: 'GET',
		url: 'json/blog.json',
		dataType: 'json',
		success: function(reponse){
		
			config.isAjax = false;

			var data = reponse.list;
			var sum = reponse.list.length;
			
			var result = '';
			
			/************業務邏輯塊:實現拼接html內容並append到頁面*****************/
			
			//console.log(offset , size, sum);
			
			/*如果剩下的記錄數不夠分頁,就讓分頁數取剩下的記錄數
			* 例如分頁數是5,只剩2條,則只取2條
			*
			* 實際MySQL查詢時不寫這個
			*/
			if(sum - offset < size ){
				size = sum - offset;
			}

			
			/*使用for循環模擬SQL里的limit(offset,size)*/
			for(var i=offset; i< (offset+size); i++){
				result +='<div class="weui_media_box weui_media_text">'+
						'<a href="'+ data[i].url +'" target="_blank"><h4 class="weui_media_title">'+ data[i].title +'</h4></a>'+
						'<p class="weui_media_desc">'+ data[i].desc +'</p>'+
					'</div>';
			}

			$('.js-blog-list').append(result);
			
			/*******************************************/
			
			/*隱藏more*/
			if ( (offset + size) >= sum){
				$(".js-load-more").hide();
				config.isEnd = true; /*停止滾動加載請求*/
				//提示沒有了
			}else{
				$(".js-load-more").show();
			}
		},
		error: function(xhr, type){
			alert('Ajax error!');
		}
	});
}

基本上與最初寫的是一樣的。

示例代碼托管在Github: https://github.com/52fhy/loadmore

-- 全文完 --


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM