當(dāng)Cordova 的CDVViewController正常加載網(wǎng)頁(yè)后塘慕,我們可能會(huì)面臨更多來(lái)自頁(yè)面點(diǎn)擊事件以及加載的問(wèn)題状您。以下所述是我們項(xiàng)目中所遇到的點(diǎn)擊問(wèn)題及對(duì)應(yīng)的解決方案浑彰。
在項(xiàng)目中我們沒(méi)有用到Cordova所現(xiàn)有的plug-in集乔,而是根據(jù)需求開(kāi)發(fā)了自己的插件储矩。此插件可以完成一般的推出視圖等功能锌云。
注:我并不直接闡述最終解決方案荠医,而是闡述整個(gè)優(yōu)化歷程。如果要直接看最終方案,請(qǐng)直接參閱第三點(diǎn)彬向。
點(diǎn)擊問(wèn)題的產(chǎn)生:
剛開(kāi)始兼贡,我們選擇了使用onclick的方式來(lái)響應(yīng)頁(yè)面上的點(diǎn)擊事件,但是效果與原生相差甚遠(yuǎn)娃胆,延時(shí)太大(300ms)遍希。據(jù)了解是這段延時(shí)是為了判斷用戶是否會(huì)觸發(fā)雙擊,真是醉了里烦。此時(shí)我們考慮到的方法是使用ontouch替代onclick凿蒜,touch事件確實(shí)能夠做到看似與原生一樣的點(diǎn)擊反應(yīng),但如果單純將頁(yè)面中的元素添加了touch事件胁黑,你將會(huì)發(fā)現(xiàn)整個(gè)頁(yè)面似乎不能滾動(dòng)了废封,因?yàn)槭种敢挥|碰就觸發(fā)touchstart方法,不會(huì)觸發(fā)touchmove方法别厘。OK虱饿,填坑開(kāi)始了。
1触趴、我們首先采用了一個(gè)比較污的招式氮发。touchstart方法一觸發(fā)就會(huì)執(zhí)行function,沒(méi)有touchmove觸發(fā)的機(jī)會(huì)冗懦。我們就延時(shí)touchstart爽冕,不管你是要點(diǎn)擊還是要滾動(dòng),touchstart方法始終是延時(shí)100ms后觸發(fā)(比300ms體驗(yàn)好多了)披蕉。如果在這100ms里你觸發(fā)了touchmove方法颈畸,那么,我們將終止touchstart的方法没讲。這樣touchmove就得以生存了眯娱。以下js代碼由于也是現(xiàn)學(xué)現(xiàn)用,所以肯定不怎么優(yōu)雅爬凑。
businessListB[i].num = i;
businessListB[i].addEventListener("touchstart", function ()
{
tag = businessListB[this.num].id;
if (tag == null )
{
return;
}
this.touchEventTimer = setTimeout(function()
{
cordova.exec(function success() {},
function failure() { },
"CDVPlugin", "onCellClicked", [tag]);
},100); // 延時(shí)100ms
}, false);
businessListB[i].addEventListener("touchmove", function()
{
clearTimeout(this.touchEventTimer); // 取消延時(shí)
this.touchEventTimer = false; // 終止touchstart方法
}, false);
剛使用上這套方案時(shí)發(fā)現(xiàn)徙缴,哇塞,完美嘁信!可是把玩時(shí)間一長(zhǎng)于样,就發(fā)現(xiàn)了新的問(wèn)題:有時(shí)圖片的點(diǎn)擊效果出來(lái)了,但是沒(méi)有執(zhí)行點(diǎn)擊后的下一步動(dòng)作潘靖。
這是因?yàn)閹缀鯖](méi)有人穿剖,在用手指點(diǎn)擊屏幕時(shí),每次都保持垂直點(diǎn)擊卦溢!
意思是糊余,有些人明明是想點(diǎn)擊秀又,不是滾動(dòng)。但是在點(diǎn)擊下去的瞬間啄刹,在touchstart方法的100ms中涮坐,手指略微的往前移動(dòng)了一點(diǎn)。這種感覺(jué)自己不會(huì)感受到誓军,但是系統(tǒng)能捕捉到袱讹。說(shuō)白了就是手指按下去時(shí)會(huì)有一點(diǎn)點(diǎn)緩沖。是的昵时,你move了捷雕,那么你touchstart方法將不會(huì)執(zhí)行!想明白這點(diǎn)之后我可以90%以上概率重現(xiàn)這個(gè)bug壹甥!
有些人可能會(huì)說(shuō)救巷,是不是100ms太長(zhǎng)了,減少點(diǎn)時(shí)間試試句柠∑忠耄可是這時(shí)間是受約束的,也就是說(shuō)你還要保證你的滾動(dòng)事件正常觸發(fā)溯职。幾次時(shí)間調(diào)整實(shí)驗(yàn)表明精盅,這兩個(gè)bug,不可能同時(shí)消失谜酒。這不可能是一個(gè)完美的方案叹俏!
2、這次我換了個(gè)方法僻族,著重避免點(diǎn)擊時(shí)的緩沖粘驰!還加上了touchend事件。
在touchstart方法中捕獲點(diǎn)擊時(shí)的坐標(biāo)述么,在touchmove中不斷的捕獲最終坐標(biāo)蝌数,判斷移動(dòng)距離,小于一定數(shù)字我們就判為不是移動(dòng)度秘,最后在touchend方法中執(zhí)行函數(shù)籽前。
這個(gè)“一定數(shù)字”讓我覺(jué)得,這也不會(huì)是一個(gè)完美方案敷钾。實(shí)驗(yàn)結(jié)果確實(shí)如此,每個(gè)人的操作習(xí)慣不一樣肄梨,而我卻在視圖給用戶制定一個(gè)操作規(guī)則阻荒,現(xiàn)在想想,著實(shí)不可取众羡。
3侨赡、最終被我找到了一個(gè)完美解決的方案,F(xiàn)astclick.js!羊壹!
這個(gè)文件神奇之處在于蓖宦,他不需要你用touch,你就用你的 onclick好了油猫,他能夠讓你的onclick有touch一樣的反應(yīng)速度稠茂!方法也非常簡(jiǎn)單,在html頁(yè)面中引入該文件情妖,并添加一句: FastClick.attach(document.body);
完工睬关!
目前,這種方案沒(méi)有遇到什么bug毡证,經(jīng)得住我的各種惡劣測(cè)試电爹。關(guān)于FastClick的原理,還未細(xì)究料睛。網(wǎng)上簡(jiǎn)單看了下丐箩,是因?yàn)樗麜?huì)捕捉頁(yè)面中的所有點(diǎn)擊事件,并且將其替換為自己的方法恤煞。待有機(jī)會(huì)我再好好研究下屎勘。
FastClick鏈接:https://github.com/ftlabs/fastclick
其實(shí)很多優(yōu)化方案,Cordova官網(wǎng)上已經(jīng)告訴我們了阱州,只恨我當(dāng)時(shí)沒(méi)耐心看完挑秉。詳情請(qǐng)戳:
http://cordova.apache.org/docs/en/latest/guide/next/index.html#2-performance-considerations
更直觀的優(yōu)化建議:
http://coenraets.org/keypoint/phonegap-performance/#0
(進(jìn)入網(wǎng)站后往左滑)
期待大家更好的建議,多多交流苔货!