最近剛做完一個移動端的項目,產品之無敵,過程之艱辛,我就不多說了,記錄下在這個項目中遇到的問題,以防萬一,雖然這些可能都是已經被N多前輩解決掉了的問題,也放在這裡,算是為自己漫漫前端路鋪了一顆小石子兒吧,也在文末留下自己未能解決的疑問,希望看到的朋友能解惑。 都知道做移動端的開發,在電腦上調試好了的 ...
最近剛做完一個移動端的項目,產品之無敵,過程之艱辛,我就不多說了,記錄下在這個項目中遇到的問題,以防萬一,雖然這些可能都是已經被N多前輩解決掉了的問題,也放在這裡,算是為自己漫漫前端路鋪了一顆小石子兒吧,也在文末留下自己未能解決的疑問,希望看到的朋友能解惑。
都知道做移動端的開發,在電腦上調試好了的東西,放在手機里可能真的秒秒鐘就炸了,我發誓絕對沒想到炸的這麼快。。。
1、IOS監聽不到input框輸入中文的keyup事件
這個小標題好像不太明確,大概就是,APP中有一個列表顯示的頁面,頁面上有個搜索功能,使用keyup監聽input框,每一次keyup都去檢索一下緩存數據有沒有符合的數據,然而、然鵝,IOS上並沒有能在每一次keyup都去檢索,經過各種查發現,IOS的輸入法(不管是第三方還是自帶)能檢測到英文或者數字的keyup,檢測不到中文的keyup,(至於標點那些,就沒有深究了),在輸入中文之後需要點擊回退按鍵,才會開始搜索,我自己能想到的辦法就是定時檢測setInterval,我也只能想到這辦法了,但是總覺得不太好,於是搜索到了這個辦法(http://blog.csdn.net/lytlx/article/details/50845259), 把keyup事件換成“input”和“propertychange”事件。
oninput 是 HTML5 的標準事件,對於檢測 textarea, input:text, input:password 和 input:search 這幾個元素通過用戶界面發生的內容變化非常有用,在內容修改後立即被觸發,不像 onchange 事件需要失去焦點才觸發。oninput 事件在主流瀏覽器的相容情況如下:
oninput 事件在 IE9 以下版本不支持,需要使用 IE 特有的 onpropertychange 事件替代,這個事件在用戶界面改變或者使用腳本直接修改內容兩種情況下都會觸發,有以下幾種情況:
- 修改了 input:checkbox 或者 input:radio 元素的選擇中狀態, checked 屬性發生變化。
- 修改了 input:text 或者 textarea 元素的值,value 屬性發生變化。
- 修改了 select 元素的選中項,selectedIndex 屬性發生變化。
在監聽到 onpropertychange 事件後,可以使用 event 的 propertyName 屬性來獲取發生變化的屬性名稱,這樣看來,oninput & onpropertychange 似乎是監聽輸入框值變化的最佳方案。
原來的代碼:
$(".ui-searchbar-input input").keyup(function () {
////
});
修改後的代碼:
$(".ui-searchbar-input input").bind("input", function () {
////
});
這樣一改之後,IOS也能正常啦~~~~
2、使用touchstart、touchmove、touchend導致頁面不能滑動
頁面上有個水滴狀的圖片,要求水平拖動修改餘額顯示,自然而然想到的就是用touchstart、touchmove、touchend來搞定了,由於是初次使用,免不得會偷懶,從網上找了一些使用代碼來縫縫補補,改成自己想要的效果,以下是初始代碼,也就是導致頁面不能滑動的罪魁禍首:
$("#img-balance").on("touchstart", function (e) {
var touches = e.touches[0];
oW = touches.clientX - $(this).offset().left;
oH = touches.clientY - $(this).offset().left;
$(document).on("touchmove", function (event) {
event.preventDefault();
}, false);
});
$("#img-balance").on("touchmove",function(e){
var touches = e.touches[0],
oLeft = touches.clientX - oW;
if (oLeft < 20) {
oLeft = 20;
} else if (oLeft > document.documentElement.clientWidth - 45) {
oLeft = document.documentElement.clientWidth - 45;
}
$(this).css("left", oLeft + "px");
mainModule.showBalance(0);
});
$("#img-balance").on("touchend",function(){
$(document).off("touchmove", function (event) {
event.preventDefault();
}, false);
});
以上代碼能完成我想要的效果,在電腦上玩兒的好好的,結果放在手機上就跪了,原來可以上下滑動的頁面,只要一滑動圖片,頁面就不能上下滑動了,再檢查了一下代碼,表示完全不清楚為什麼要在touchstart和touchend裡面綁touchmove事件,這可能也是拷別人代碼的弊端吧,因為不知道原因,索性就把那兩段代碼給刪了,結果頁面莫名其妙的就滿血複活了,以下是修改後的代碼:
$("#img-balance").on("touchstart", function (e) {
var touches = e.touches[0];
oW = touches.clientX - $(this).offset().left;
});
$("#img-balance").on("touchmove",function(e){
var touches = e.touches[0],
oLeft = touches.clientX - oW;
if (oLeft < 2) {
oLeft = 2;
} else if (oLeft > document.documentElement.clientWidth - 35) {
oLeft = document.documentElement.clientWidth - 35;
}
$(this).css("left", oLeft + "px");
mainModule.showBalance(0);
});
因為刪掉off代碼之後touchend裡面幾乎沒有東西了,索性就把touchend也刪了,發現並不影響效果,就偷著樂了,後經查證發現,頁面不能滑動,就是因為那個event.preventDefault()阻止了事件的預設行為(頁面滑動???),所以,把它刪掉就好了。
3、部分手機滑動不流暢
頁面中的滑動刷新使用的是iscroll,鬱悶的是我周邊的所有人的手機滑起來都是順暢的不要不要的,只有我的,完全劃不動,卡得抓狂,鑒於只有我的手機有這個問題,所以我把它放在了項目的最後來解決,甚至抱著只有我一個覆蓋率或許可以不修複這個問題的小僥幸,現在想想真是慚愧(主要是我旁邊的大牛說,“你要知道有一個你,就有千千萬萬個你”,你贏了)。
在網上查的時候發現還真是有千千萬萬個我,發現很多人都遇到過這個問題,其中有我覺得可信度較高的知乎(https://www.zhihu.com/question/21938954)、CSDN(http://blog.csdn.net/bbsyi/article/details/50915049 ,http://blog.csdn.net/ml01010736/article/details/50999335)等,還有一些不知名網站,都給出評論說可行的解決方案,無外乎就是以下幾種(多是知乎總結出來的):
1) iScroll v5.1.3 momentum: true (我用的iscroll的版本沒這麼高,所以就沒有試過這種方法,不知是否可行)
2) 關閉probeType屬性 (傳說是因為這個啟用監聽滾動狀態的很耗性能,關閉這個屬性滑動就會流暢很多)
3)給scroll元素增加css樣式:-webkit-transform:translate3d(0,0,0);
以上3種方式,我試過後兩種,項目中的iscroll初始化為:
_myScroll = new IScroll('#wrapper', {
probeType: 3,
mouseWheel: true,
click: true
});
wrapper中的DOM為:
<div id="wrapper">
<div id="scroller">
<div id="scroller-pullDown">
<span id="down-icon" class="icon-double-angle-down pull-down-icon"></span>
<span id="pullDown-msg" class="pull-down-msg">下拉刷新</span>
</div>
<div id="scroller-content">
<div class="div-list">
</div>
</div>
<div id="scroller-pullUp">
<span id="up-icon" class="icon-double-angle-up pull-up-icon"></span>
<span id="pullUp-msg" class="pull-up-msg">上拉刷新</span>
</div>
</div>
</div>
先是第三種,給scroll元素增加css樣式,scroll元素是#scroller,上午做測試的時候用的是#scroller-content(啊啊啊啊啊!!!)現在才發現元素選錯了,不知道是不是這個原因導致的第三種方法沒有生效(存疑)。
第二種方法,註釋掉實例化時的probeType屬性,然而發現,並沒有什麼用。。。於是又開啟了茫茫網路上的撈針行動。
最終,在CSDN(http://blog.csdn.net/ml01010736/article/details/50999335)上找到了可行辦法:
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
偶,這中間還有個小插曲,為瞭解決這個滑動問題,一度傻逼得懷疑是不是沒有寫fastclick的原因,後來加上了並沒有解決問題,也忘記了刪掉,還導致後面的a標簽需要點擊多次才能跳轉鏈接的問題,鬱悶。。。
加上了這句代碼之後,我的手機頁面終於也是順順暢暢的了,哈~舒心~就喜歡遇到這種花時間就能解決的問題
以下是問題:
1、在解決touchstart、touchmove、touchend引發的問題的時候順帶解決了一個不知名bug,這個頁面上有個輸入框,每當輸入框開始輸入數據後頁面就會白屏,只留下孤獨的游標在那裡閃爍,輸入點擊完成後頁面又顯示出來了,這個只是IOS上的問題,奇怪的是,還沒有開始找原因,解決了頁面卡死事件後這個問題也莫名其妙的不見了,簡直靈異。。。
2、解決最後一個問題的時候因為傻逼加上了fastclick,又引發了我的頭腦風暴,fastclick能夠解決移動端的300ms延遲問題,那按理說我加上了之後點擊應該比之前反應快一點才對,為什麼反而需要多次點擊才能跳轉鏈接呢????
做這個總結的時候已經是項目發版本的晚上8點,加班狗已哭暈在廁所,這一次的項目我學到不少好東西,雖然連加了兩周的班,畢竟無欲無求,也就無所謂了。