頁面很簡單,先上效果圖
吐槽
某日,暴雨,南京的某個角落
領導: 排面,來一下,我有一個小想法 。
我:怎么了,海哥,是不是有新功能要做,我等這一天好久了(MMP 就你想法多,聽聽歌撩撩妹不好嗎)。
領導: 最近用戶也突破120萬了,項目處在穩(wěn)定的維護期,所以我想新增加一個小功能 。
我: 什么功能你說吧,作為高級工程師,公司的顏值擔當,沒有什么是我解決不了的。
領導:我想做個一鍵洗車功能,給用戶展示附近的洗車場,然后提供導航。用 h5實現(xiàn),后期方便更新維護,你來寫 h5和 iOS 。
我:(What?那我的王者榮耀怎么辦)恩,您真是有遠見,站在用戶角度考慮。但我們產品和 UI 剛離職,沒有原型和效果圖,所以這個想法是不是有點不成熟 。
領導:只要有夢想,人人都是設計師 。
我:(ZZ....)
第二天來公司,我就收到了一副慘無人道的效果圖,它大概是這個樣子
我怎么怎么辦,我也很絕望啊。
正文
前面加載數(shù)據(jù)的基本操作不做過多描述,直接進入正題。
判斷上拉條件
此處后臺接口除了返回一個頭部信息外 + 10條列表數(shù)據(jù),此時的參數(shù) pagenum 為1。當上拉到頁面底部時,再發(fā)一次 ajax 請求,參數(shù) pagenum為2,以此類推。那么,怎么判斷頁面剛好到了底部。
假設此時是剛加載完數(shù)據(jù)的初始狀態(tài),可以看到還有一部分數(shù)據(jù)沒有加載出來,處在在屏幕外。當此時手指往上滑動,進入下圖這個狀態(tài)。
所以當監(jiān)聽頁面的 touchmove事件。 所有內容高度 = 屏幕高度 + 滑動高度時 。發(fā)送 ajax 請求,加載下一頁數(shù)據(jù)。
windowH = $(window).height();
scrollH = $(document).scrollTop();
documentH = document.documentElement.scrollTop==0? document.body.scrollHeight : document.documentElement.scrollHeight;
if (windowH + scrollH >= documentH - 20) {
console.log("這里頁面到達底部");
//執(zhí)行 ajax 操作
$.ajax({
datatype : "JSON",
type : "POST",
url : "jiekou.htm",
timeout : 15000,
async:true,
data : { key:value,pagenum:pagenum},
error : function (e) {},
success : function(json) {
//for 循環(huán)加載數(shù)據(jù)
pagenum = parseInt(pagenum) + 1;
}
});
}
這里選擇的是異步請求,同步請求當用戶網(wǎng)絡差或者我們服務器速度慢時,會卡死頁面,并且需要等到timeout 之后才能進行下一次刷新加載,嚴重影響用戶體驗。
問題關鍵
但是此時出現(xiàn)了一個新的問題,當滑動到底部時,上面的輸出語句 console.log("這里頁面到達底部") 會調用數(shù)十次。因為 touchmove 事件一直響應,只要滿足我們的判斷條件,就會進入方法內執(zhí)行輸出語句。
因為我們前面選擇的異步請求,所以ajax 請求也會執(zhí)行數(shù)十次,就會出現(xiàn)大量的重復數(shù)據(jù)。解決這個問題有兩個辦法:
- 改為同步請求,一次加載未完成不會進行下一次請求。
- 繼續(xù)使用異步,新增一個參數(shù)進行判斷,當前后兩次的pagenum不同才進行新的請求。
第一個方法直接放棄吧,不然會被領導搞死。
if (windowH + scrollH >= documentH - 20) {
if (pagenum != lastpangenum) {
//當此時的pagenum跟上一次不同時,才調用
lastpangenum = pagenum;//更新lastpangenum
//執(zhí)行 ajax 操作
}
}
這樣做得話問題好像已經(jīng)被解決了。但是當你把 timeout 參數(shù)改的非常小,模擬網(wǎng)絡差請求超時情況,發(fā)現(xiàn) if (pagenum != lastpangenum) 條件永遠不執(zhí)行。因為沒有走 success 方法,pagenum沒有+1所以我們需要處理請求失敗的情況。在 error 方法里打破 pagenum = lastpangenum 均衡。完整的代碼如下:
if (windowH + scrollH >= documentH - 20) {
if (pagenum != lastpangenum) {
lastpangenum = pagenum;//更新lastpangenum
//執(zhí)行 ajax 操作
$.ajax({
datatype : "JSON",
type : "POST",
url : "jiekou.htm",
timeout : 15000,
async:true,
data : { key:value,pagenum:pagenum},
error : function (e) {
lastpangenum = lastpangenum - 1;
},
success : function(json) {
//for 循環(huán)加載數(shù)據(jù)
pagenum = parseInt(pagenum) + 1;
}
});
}
}
小Tips
問題基本上就是這么多,作為一個非專業(yè)前端開發(fā),一切還在摸索的過程中。這里放上幾個常用的小方法,以備后用。
1,取當前URL 中的參數(shù)
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&#]*)/gi,
function(m,key,value) {
vars[key] = value;
}
);
return vars;
}
//用法(假設 url 為 www.baidu.com?guid=12345&token=kd1247da)
var guid = getUrlVars()["guid"];
2,獲取時間戳,時間戳與正常格式轉換
var nowtimestamp = new Date().getTime();//得到時間戳
var commentime = getLocalTime(nowtimestamp);//得到普通格式時間
function getLocalTime(ns) {
var d = new Date(ns);
var dformat = [ d.getFullYear(), d.getMonth() + 1, d.getDate() ].join('-')
+ ' ' + [ d.getHours(), d.getMinutes(), d.getSeconds() ].join(':');
return dformat;
}
3,Android平臺與iOS平臺判斷
var u = navigator.userAgent;
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android終端
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios終端
if(isAndroid ===true){
}else if(isiOS===true){
}
4,iOS返回不響應
<a href="#" onclick="window.history.back();return false;>
//在后面加return false,屏蔽 a 標簽的默認操作
持續(xù)更新中...........
結語
整個功能做下來持續(xù)了一個多星期,也遇到過不少問題,對于 h5的很多底層原理知之甚少,更談不上優(yōu)化。最近在看俞甲子那本程序員的自我修養(yǎng)--鏈接、裝載與庫 發(fā)現(xiàn)自己對于一些底層知識越來越感興趣,總覺得它像武林里的內功,一通則百通。好吧,扯得有點遠了。等等.....領導好像又在叫我了.......