巨大的建築,總是由一木一石疊起來的,我們何妨做做這一木一石呢?我時常做些零碎事,就是爲此。
這是對的,但是我沒有說過這句話! —— 魯迅
整理一下js插件的編寫,這裏以手機端H5分頁舉例。
即一共有1000條數據,每次只加載20條,當滑到底端的時候再默認加載20條,直到將所有數據加載完成。
封裝性
將自己的代碼隔開,使其他代碼不會受到任何影響。
(function (win,$) {
})(window,$);
$是Jquery,window的作用是將自己寫的插件暴露出來,讓window可以直接調用.
組成部分
定義一個插件名,包括要傳輸的參數,即一個類的定義。
定義插件,也是要在這裏進行參數傳遞。
/***
* 插件名,首字母大寫,可以向對待類一樣對待,如:new MobilePage()
* @param url 要請求的地址
* @param type get,post,put等
* @param data 要傳輸的數據.
* @param callcack success後要執行的函數.
*/
var MobilePage = function (options) {
this.url = options.url;
this.type = options.type;
this.data = options.data;
this.callback = options.callcack;
this.pageParams = {
//對應 sql中的 limit(0,3)
start:0,
length:3
};
//當次請求的數據長度,有可能=pageParams.length ,也有可能 < pagePaarams.length(最後一頁)
this.dataLength = this.pageParams.length;
this.dataTotal;//記錄一下數據的總長度
}
給插件增加方法
對插件添加方法,添加方法,要加到prototype中,這樣相當於多個對象公用一套方法(跟java中的存儲一樣).
MobilePage.prototype = {
init:function () {
}
}
當然,更好的寫法是一個方法一個方法的寫,上面這種寫法會將MobilePage的prototype中已有的方法覆蓋掉.
MobilePage.prototype.init = function {
}
或者用JQuery的extend方法進行加載
MobilePage.prototype = $.extend(MobilePage.prototype,{
init:function () {
}
});
將插件的使用暴露出來.
一般一個頁面只有一個分頁,這時候只new一次,可以提供一個對象,自動new出來,並暴露給window.
win.MobilePage = MobilePage;
win.mobilePageUtil = {
request:function (url,type,data,callback) {
return new MobilePage(url,type,data,callback);
}
}
核心方法
請求方法
類似於$.ajax等.
request:function () {
var me = this;
me.data.pageParams = JSON.stringify(me.pageParams);
$.ajax({
type:me.type,
url: me.url,
data:me.data,
dataType: "json",
success: function (result) {
console.info(result);
if (result.code == 'SUCCESS') {
var data = result.data;
if (me.callback) {
me.callback(data);
}
//這個data應該是一個數組,求一下length
me.dataLength = data.length;
me.dataTotal = result.total;
}
}
});
}
將$.ajax封裝一下,如果成功的話,則執行回調方法。並設置自己的一些屬性,包括一共有多少數據,當前返回數據有多少條,便於分頁的設置。
下一頁方法
nextPage:function () {
this.pageParams.start += this.dataLength;
//調用請求方法.
if (this.pageParams.start < this.dataTotal) {
this.request();
} else {
console.info("我已經到底線了,沒有數據可加載了")
}
},
修改start數值,判斷是否加載已完成.
增加觸發事件的方法
這裏是用的window的scroll事件,來實現,這裏有3個高度。
- contentH 內容的高度,也就是document的高度。
- viewH 屏幕的高度,也就是window的高度
-
scrollTop 滾動的高度,當滾動到最底下的時候,理論上 contentH == viewH + scrollTop
所以現在用 contentH == viewH + scrollTop 來判斷是否滑到了最底部,假如滑到了,則觸發事件,重新從服務器端請求數據.
init:function () {
var me = this;
//添加下拉觸發的事件
$(win).scroll(function () {
var contentH = $(document).height();
var viewH = $(this).height();
var scrollTop = $(this).scrollTop();
console.info("contentH:" + contentH);
console.info("viewH:" + viewH);
console.info("scrollTop:" + scrollTop);
if (viewH + scrollTop == contentH) {
//拉到底了還拉.
console.info("已經拉到底了,你還拉");
//發起請求.
me.nextPage();
}
});
},
關於 var me = this;
因爲this經常變換,用變量記錄當時this的指向.
調用
mobilePageUtil.request({
url: api_host + "/question/mobile/study",
type: 'GET',
data: {questionType: 'CHOICE'},
callback: makeAddtionHtmls
});
由於在插件中已經將mobilePageUtil 通過 window.mobilePageUtil 暴露給了window,所以這裏可以直接使用
makeAddtionHtmls爲具體的方法,注意可以接受一個list的參數.
function makeAddtionHtmls(questionList) {
console.info(questionList);
}
全部代碼展示
上面介紹的是思路,代碼稍有衝突,代碼以下面的爲準.
/**
* 手機端分頁,上拉加載,用scroll事件,嵌入到App中去.
* @author liuzhenning
* @version 0.0.1
* @since 0.0.1 2019/02/27
*/
//封裝成一個分頁插件,自己寫,將自己的代碼隔離開
(function (win,document,$) {
/***
* 插件名,首字母大寫,可以向對待類一樣對待,如:new MobilePage()
* @param url 要請求的地址
* @param type get,post,put等
* @param data 要傳輸的數據.
* @param callcack success後要執行的函數.
*/
var MobilePage = function (options) {
// var MobilePage = function (url,type,data,callcack) {
//仿照$.ajax的模式,傳輸對象,便於維護,方便增加屬性
this.url = options.url;
this.type = options.type;
this.data = options.data;
this.callback = options.callback;
this.pageParams = {
start:0,
length:3
};
//當次請求的數據長度,有可能=pageParams.length ,也有可能 < pagePaarams.length(最後一頁)
this.dataLength = this.pageParams.length;
this.dataTotal;//記錄一下數據的總長度
//初始化
this.init();
//調一次加載數據,首頁.
this.request();
}
//對插件添加方法,添加方法,要加到prototype中,這樣相當於多個對象公用一套方法(跟java中的存儲一樣).
MobilePage.prototype = {
init:function () {
var me = this;
//添加下拉觸發的事件
$(win).scroll(function () {
var contentH = $(document).height();
var viewH = $(this).height();
var scrollTop = $(this).scrollTop();
console.info("contentH:" + contentH);
console.info("viewH:" + viewH);
console.info("scrollTop:" + scrollTop);
if (viewH + scrollTop == contentH) {
//拉到底了還拉.
console.info("已經拉到底了,你還拉");
//發起請求.
me.nextPage();
}
});
},
nextPage:function () {
this.pageParams.start += this.dataLength;
//調用請求方法.
if (this.pageParams.start < this.dataTotal) {
this.request();
} else {
console.info("我已經到底線了,沒有數據可加載了")
}
},
request:function () {
var me = this;
me.data.pageParams = JSON.stringify(me.pageParams);
$.ajax({
type:me.type,
url: me.url,
data:me.data,
dataType: "json",
success: function (result) {
console.info(result);
if (result.code == 'SUCCESS') {
var data = result.data;
if (me.callback) {
me.callback(data);
}
//這個data應該是一個數組,求一下length
me.dataLength = data.length;
me.dataTotal = result.total;
}
}
});
},
reset:function () {
this.pageParams.start = 0;
}
}
//一般一個頁面只有一個分頁,這時候只new一次,可以提供一個對象,自動new出來,並暴露給window.
win.MobilePage = MobilePage;
win.mobilePageUtil = {
//只request1次,之後的request,是靠事件觸發的,也就是再request的時候,那參數直接置爲默認了,無需reset.
request:function (options) {
return new MobilePage(options);
}
}
})(window,document,$);
其他
因爲手機端,要考慮內存容量的問題,所以這裏用jquery的話會有點大,小編這裏使用的是zepto,效果一樣的。