移動端的應用越來越多的開始采用html5來實現的。Html5有許多新特性需要開發者注意,比如css3,touch事件等等。比如做一個輪播圖,分析其實現要領,有三點:
1.圖片的輪播效果對應的css 樣式;
2.定時操控函數改變css樣式來實現動畫;
3.綁定觸摸事件對動畫的播放進行控制。
在原來的桌面js開發中,jQuery應用非常廣泛;而在移動端的js開發中,Zepto更勝一籌。Zepto為很大程度上接近兼容jQuery的js 輕量lib庫,只考慮對主流移動瀏覽器web-kit核心進行支持。
在觸摸事件的綁定上,采用Zepto的swipeRight和swipeLeft事件處理:
$(cache.player).swipeLeft(function(){
處理動畫的播放控制;
});
這就是典型的事件綁定回調函數,與常見的
$(btn).click(function(){
處理點擊事件;
});
點擊綁定非常近似,
只不過事件的名字不同而已。
在chrome dev tools順利通過iphone和galaxy的模擬,但是在iphone,android真機內嵌瀏覽器下,還是出現了意想不到的問題:
1. 在iphone上滑動基本無效;
2. 在小米和三星上,左滑幅度大的話等於退出移動客戶端的內嵌瀏覽器。
這是為什么呢?第二個問題移動客戶端的內嵌瀏覽器左滑幅度大的問題是內嵌瀏覽器在滑動下自帶默認操作,方便在內嵌瀏覽器和客戶端實現切換吧。
第一個問題就比較頭痛了,閃過了debug的念頭。在手機端debug,難道要裝個debug工具在手機上?或者來個真機模擬測試?男默女淚,人艱不拆。以上想法實現起來都沒有現成的,可行的目前只有jsConsole。JsConsole的調試方法,就是包含一個http://jsconsole.com/生成的Javascript文件。在調試時,移動端會連接到遠程服務器上並把console.log的內容在服務端上顯示,達到debug的目的。
相應的也對zepto的touch事件代碼進行了分析:
$(document) .on('touchstart MSPointerDown pointerdown', function(e){})
.on('touchmove MSPointerMove pointermove', function(e){})
.on('touchend MSPointerUp pointerup', function(e){
…
if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) ||
(touch.y2 && Math.abs(touch.y1 - touch.y2) > 30)){
//swipeTimeout = setTimeout(function() {
touch.el.trigger('swipe')
touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))
touch = {}
//}, 0)
}
…
})
代碼中可見有三個事件綁定函數。這三個綁定事件為touchstart,touchmove,touchend。在滑動時,手剛點上觸摸屏,會觸發touchstart事件,移動時每隔十幾毫秒會進行touchmove事件的觸發,手從觸摸屏上移走會觸發touchend事件。
在W3C的touchEvent文檔中有callback函數的e有說明
interface TouchEvent : UIEvent {
readonly attribute TouchList touches;
readonly attribute TouchList targetTouches;
readonly attribute TouchList changedTouches;
readonly attribute boolean altKey;
readonly attribute boolean metaKey;
readonly attribute boolean ctrlKey;
readonly attribute boolean shiftKey;
};
其中touches和changedTouches中有對觸摸點對象的封裝
對於任何滑動事件的處理,思路如下:在touchEnd和touchStart觸發時做一個touch對象的數據記錄,比較兩者的移動距離來界定其是左滑還是右滑來進行相應回調的觸發即可進行左滑、右滑的事件處理。
iphone中內嵌瀏覽器Zepto為什么存在問題呢,主要是其在touchEnd中回調時啟用了
swipeTimeout = setTimeout(function() {
touch.el.trigger('swipe')
touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))
touch = {}
}, 0) setTimeout定時函數。這個定時函數在iphone上經常沒有機會執行。導致程序的swipeLeft,swipeRight事件在內嵌瀏覽器無法被觸發導致,在safari和chrome下沒有問題。這也說明了zepto的兼容性比較差。
移動端的問題基本上是對舊有事件體系的一種擴充,由於移動端存在多種瀏覽器的兼容性的問題,因此一些個性化的問題會存在。相信這些問題在HTML5長期的改進中會得到解決。
參考文獻:
1.觸摸事件: http://www.w3.org/TR/touch-events/
2.關於js定時器的深入研究:http://ejohn.org/blog/how-javascript-timers-work/