交互篇
從PC到移動端,視覺和交互是用戶能直接感受到的差異。在視覺篇中已經提到,移動設備的物理屬性一部分影響到視覺,另外一些部分將影響到交互。那么,移動設備影響交互的物理屬性都有哪些變化呢?對於這個問題,相信大家都早有答案。傳統PC的輸入設備相對單一,一般情況下只有鼠標和鍵盤,而移動設備的硬件就變得非常豐富,觸屏、觸控筆、麥克風、陀螺儀和GPS等一應俱全。下面咱們就聊聊在移動Web開發中有關交互的一些問題。
手勢
手勢是移動Web與PC Web開發在用戶接口上最大的一個差異,PC端主要考慮的是鼠標操作,鼠標的運行軌跡就比較簡單,jQuery對鼠標事件的支持也只有11個,基本上已經算最全的鼠標事件庫,這里我就不細說,可以自行查看API jQuery Mouse Event。
下面這幅圖展示了基本的手勢圖例:
就目前來說,大多數的移動Web應用場景,使用的手勢相對比較簡單,主要還是單指手勢tap、long tap或double tap。我遇到的案例中,使用手勢相對復雜的應用應當是組圖產品。360搜索移動版的圖庫手勢實現,是我認為目前移動端組圖展示的一個最佳實踐。在這個案例中手勢已經具備一定的復雜程度,使用到了單指和雙指手勢,包括:double tap、swipe、scale,並且使用的手勢與非常貼近組圖產品的實際需求,所以,360圖片搜索對於如何正確應用觸屏手勢來說非常具有參考意義。
大家可以使用手機掃描下面這個二維碼,查看360圖片搜索的的案例:
使用手勢的技術並不復雜,如何在Web應用中選擇一個合適的手勢交互才是值得深思的問題。Touch Gesture Guide這份PDF非常全面的分解了所有觸屏手勢,以及手勢動作的含義,同時,還可以參考騰訊CDC團隊在早期的一篇文章《移動設備手勢設計初探》。
觸屏事件
觸屏事件是一個較為技術性的話題,但是在這篇文章中又不得不提到,因為它太重要了。所有的手勢都是使用觸屏事件的技術實現,現在在iOS和Android下通用的是Touch事件模型,Touch事件模型可以參見Apple開發者文檔《Handling Events》的這篇文章,在iOS下還有一個特有的Gesture事件模型,在那篇文章中都有詳細的介紹。
在觸屏事件模型中,傳統的click、mouse事件都是被模擬出來的,理論上應該是在touchend事件之后被觸發,如圖7:
在Touch事件模型中有一個必須注意的問題,click事件是在touchend之后延遲300ms觸發,如圖8:
而就是這個延遲300ms,導致了移動Web開發非常著名的點擊穿透問題,《【初窺javascript奧秘之事件機制】論“點透”與“鬼點擊”》這篇文章舉的例子比較好,一看就能明白什么是點透問題。關於點透問題也有很多已經出現了很多解決方案,如FastClick。
上面沒有提到Windows Phone,因為微軟為移動設備專研發了PointerEvent事件模型,目前只有IE10+才支持,所以Web應用在Windows Phone下運行,要做PointerEvent兼容。在文章《瀏覽器的統一指針事件:Pointer Event》中講述了它的一些歷史和原理,並附了一些實例文章。
局部區域滾動
我先說明下我對它的定義,以免有人和我理解不同。局部區域滾動就是給塊級元素賦予高寬和overflow:scroll
,代碼如下:
div {
width: 320px;
height: 500px;
overflow: scroll;
}
這么做在PC瀏覽器下固然沒有任何問題,但是移動端瀏覽器由於輸入設備(也就是上面說的手勢)的差異,導致局部區域與<body>
全局滾動相沖突。當手指停留在局部區域時,瀏覽器需要識別你當前滾動的是全局還是局部,這樣就顯得局部區域滾動的交互相當不協調。在早期的Android系統就不支持局部區域滾動,一直到Android 4才支持的比較不錯。
局部區域滾動在移動Web開發中,應用非常廣泛,如:
- 單頁Web應用開發,可以參見我的另一篇文章《移動Web單頁應用開發實踐——頁面結構化》
- 頁面中需要滾動塊級元素,比如百度百科中的表格,圖9
目前主要有三種方法來解決局部區域滾動的問題:
- 使用
-webkit-overflow-scrolling: touch
,有兼容問題,低版本系統不支持這個特性,而且交互沖突的問題依然存在; - 使用IScroll組件,IScroll是依賴Touch事件來模擬局部滾動,所以性能上有很突出的問題,在Android手機上表現不佳;
- 在有限的應用場景使用
position: fixed
,主要適用於單頁Web應用開發,可以參見jQuery Mobile的視圖模型以及視圖切換的例子;
IScroll組件存在的意義,對與單頁Web應用來說是不言而喻,它要解決的不僅僅是多視圖共存的問題,還包括數據展示與交互的問題,這在我那篇頁面結構化的文章中都有詳細的說明。
瀑布流
由於移動設備的屏幕和手勢的緣故,瀑布流將會是一種主要的信息展示的方式,如下:
圖11,當頁面滾動到底部或點擊“加載更多”按鈕,加載下一頁數據
對於瀑布流這種信息展現形式,會有兩種常見的交互方式:
- Pull up to load more,向上拉加載更多
- Pull down to refresh,向下拉刷新
上拉操作可以監聽scroll
事件來實現,這在很多產品中都能找到例子。但是,下拉操作在全局滾動下無論如何都是無法實現的,所以就需要借助於IScroll這樣的組件,可以參見我寫的例子Views with IScroll
點擊反饋
由於事件模型的變化導致另一個常見問題就是點擊反饋,在PC端完成“可點擊區域”的交互可以使用:hover
、:visited
這樣的偽類來實現各種狀態效果,但這樣的常用做法在移動開發下失效了。主要是因為如下幾個原因:
:hover
在Touch事件模型下失效;- 手指的觸摸面積比較大,如果可點擊區域的size太小,就很難引起用戶注意;
- 移動端很難失焦,必須點擊另一個可點擊元素才能失焦;
由於這樣的交互變化,就需要我們非常小心的去處理這些問題。具體的一些解決方案,可以到mobileTech中查找。
對於focus和blur動作,尤其需要注意文本框的一些問題,文本框獲得焦點之后,會彈出軟鍵盤,這就導致各種問題,比如:
- 在一些Android系統下,文本框組件獨占顯示,導致遮擋了一些正常顯示的元素;
- 軟鍵盤彈出后,窗體size沒有重置,導致遮擋內容;
- 在iOS下
position: fixed
元素中嵌入文本框的一些問題,可以參見《移動端web頁面使用position:fixed問題總結》
和大家分享一個小技巧,在軟件盤彈出之后,如果想點擊一個按鈕又不希望軟鍵盤收起,可以在touch事件中調用e.preventDefault()
防止軟鍵盤被收起。這個例子可參見百度移動搜索首頁的文本框,輸入內容之后,點擊右側的“X”按鈕清空輸入,但軟鍵盤不會收起。
傳感設備
就目前來說,HTML5可用的傳感設備接口非常優先,比較成熟的只有兩個:Geolocation和DeviceOrientation。使用Geolocation可以實現GPS定位、計算距離等,使用DeviceOrientation可以實現搖一搖、指南針等功能,具體可以參見下面的文章:
- HTML5 for the Mobile Web - a guide to the Geolocation API
- HTML5 for the Mobile Web: Device Orientation Events
屏幕翻轉事件orientationchange
實際也就是DeviceOrientation的一種實現。
另外,軟件盤中的語音輸入和<input type="file">
也是在產品中經常會使用到的兩個功能,尤其是<input type="file">
,它可以用來拍照上傳圖片。
小結
在交互篇中,都是與手勢交互相關的開發注意事項,這些是產品中最常見和最常用的交互,會有不全的地方,目的只是想帶入門新手熟悉移動Web開發中的交互變化