DEMO : 滾動加載示例css
關於如何實現『加載更多』功能,網上有插件可用,例如比較著名的使用iscroll.js實現的上拉加載更多、下拉刷新功能。html
但實際用起來倒是很麻煩。因爲是第三方插件,要按照對方定義的方法使用,用起來總感受很不順心。再加上iscroll.js自己並無集成加載更多的功能,須要進行自行擴展。想繼續使用iscroll.js實現加載更多功能的,上面給的連接能夠看看。git
h5項目裏須要實現簡單的分頁功能,因爲是移動端,考慮用『加載更多』會更好,而不是PC端的翻頁。github
最簡單的就是給一個加載更多的按鈕,若是還有數據,點擊下加載更多,繼續拉幾條數據;直到沒有更多數據了,隱藏加載更多按鈕。ajax
DEMO : 基於按鈕實現加載更多json
這裏提早準備好數據。
演示數據格式:blog.jsonapp
{ "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:ide
<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
-- 全文完 --