標籤:
作為一個前端,而且作為一個做移動端開發的前端,那意味著你要有三頭六臂,跟iOS開發哥哥一起打醬油,跟Android開發哥哥一起修bug...
Android vs Ios
我在webkit核心的chrome中進行開發的頁面,拿著iPhone和安卓機來進行測試,傳說中它們的瀏覽器核心也是WebKit,那麼問題來了,同樣的頁面為什麼在ios中和安卓中表現不同,出現了各種稀奇古怪的bug...
我嘗試找下兩者的根本區別:
- iOS
隨著2007年6月29日iPhone的上市,WebKit進入iPhone OS平台,經過Apple的定製,成為iPhone OS平台獨一無二的排版引擎;
- Android
在舊版本的安卓中:
熟悉Android系統和HTML編程的人可能都聽說過Android提供的一個重要類android.webkit.WebView,它繼承於View類,這是它同其它很多控制項的相似之處。不同之處在於,它能夠用來渲染網頁。當前,WebView的實現是基於現有的預設WebKit核心(Android預設瀏覽器是基於WebView構建),它不同於chromium所使用的WebKit核心,雖然它們都叫WebKit.
但是,在最新的Android 4.4 Kitkat版本中,原本基於Android WebKit的WebView實現被換成基於Chromium的WebView實現.
- 結論
由此可見,雖然它們都叫WebKit,但是WebKit和WebKit也是不同的:
讀了這篇文章:[開發人員需要瞭解的WebKit] 你就會瞭解到了,同是WebKit它也有不同的Port,它們專註於不同的部分,每個WebKit port中有共用的部分,但是也有很大一部分功能是不會共用的,其中就包括JS引擎。
所以我停止了說:「為什麼ios都行了安卓怎麼就不行呢?」,而是埋頭開始修bug...雖然有時候這些bug不是那麼好修...
什麼是WebView
作為一個前端兒,你肯定聽過WebView這個詞兒。我也聽過,也好奇過,把我的網頁放到手機上看就叫WebView啦?WebView到底是什麼呢?
其實WebView是類名或者說它是一個API(在我看來):
- 在Android中,這是個繼承於View類的類android.webkit.WebView,用來布局和渲染網頁;
- 在iOS中,這個類叫UIWebView,同樣是應用程式的UI介面。
我們前端怎麼就會對用戶端的類名這麼熟悉了呢?
如果你是個有見識的前端那麼你肯定聽過Hybrid App(混合模式行動裝置 App).這是指介於web-app、native-app這兩者之間的app,兼具“Native App良好使用者互動體驗的優勢”和“Web App跨平台開發的優勢”。
在我看來,這就是前端跟iOS開發和安卓開發一起做的事情嘛。它的實現就離不開WebView了,因為用戶端需要渲染我提供的H5頁面,那具體怎麼實現呢?我也不知道了...去問用戶端開發吧...
Touch事件
現在我們知道了手機跟手機不同,WebKit與WebKit的不同,Crowdsourced Security Testing道著,我先從頭看一下touch事件,再看看他會有什麼問題。
Touch事件:
1 touchstart:當一個手指放在螢幕上時觸發;2 touchend:當一個手指從螢幕上移走的時候觸發;3 touchmove:當一個手指已經在螢幕上並且在螢幕上移動時觸發;4 touchcancel:如果太多個手指在螢幕上或一個其他動作發生時觸發。
Touch事件中事件對象的屬性:
1 touches: 它包含了每個手指當前touch螢幕的一系列資訊;2 targetTouches: 像touches一樣,但是提供當前手指的touch資訊;3 changedTouches: 包含每一個手指的touch改變的資訊。
怎麼理解呢:
1. 當你放下一個手指的時候,上面三個屬性會提供相同的資訊;
2. 當你放下第二個手指的時候,touches對象會包含兩條資訊,每個手指都有一個;targetTouches只有在第二根手指放在了同第一根手指相同的節點上的時候會包含兩條資訊(否則的話它只包含第二根手指的資訊);changedTouches只會包含跟第二根手指相關的資訊.
3. 如果幾乎同是兩個手指觸碰螢幕,在changedTouches中會有兩個手指的資訊。
4. 如果我們在螢幕上移動手指,唯一會改變的對象是changedTouches,它會包含我們移動的一個或兩個手指的資訊;
5. 如果抬起一個手指,它的資訊會從touches和targetTouches對象中移除,但是在changedTouches會找到它的資訊;
6. 當我們把最後一個手指從螢幕上移走,touches和targetTouches對象會為空白了,但是changedTouches將會保留最後這跟手指的資訊。
touches對象中包含的每個手指的資訊列表中也有下面這些我們在滑鼠事件中熟悉的屬性:
1 identifier - 一個標識符,對於每個touch點(手指)是獨一無二的;2 target -當前手指touch的dom節點;3 clientX/clientY -touch事件發生時相對視口(viewport)的座標(包含滾動)4 screenX/screenY -相對於螢幕的座標5 pageX/pageY -相對於整個文檔的座標
[簡單的touch事件實現的拖拽小demo]
Touch事件相關tip
1.檢測裝置是否為觸控螢幕裝置:
通常我們檢測裝置是否為觸控螢幕有兩個方法,一個是通過UA還有一個就是特徵檢測:
var isTouch = !!ua.match(/AppleWebkit.*Mobile.*/) || ‘ontouchstart‘ in document.documentElement;
但是我前兩天讀了一篇非常好的文章。這樣進行判斷已經不再準確了。當筆記本為觸控螢幕的筆記本時,上面的判斷方法還是會認為他是觸摸裝置。
文章中給出了方案:我們可以通過W3C Interaction Media Features給出的方案來判斷。
W3C在Media Query Levle 4中增加了pointer類別的特徵查詢,pointer有三個條件選項:none、fine 和 coarse:
1 None,當前裝置沒有任何除鍵盤或觸控板之外的輸入方式2 Fine,當前裝置使用了滑鼠來操作3 Coarse, 表示當前裝置至少支援觸屏操作,也可能同時支援滑鼠
通過一些組合,我們就可以進行判斷了:
// 既有觸屏也有滑鼠matchMedia("(pointer:coarse)").matches && matchMedia("(pointer:fine)").matches// 只是觸屏matchMedia("(pointer:coarse)").matches && !matchMedia("(pointer:fine)").matches// 只是滑鼠!matchMedia("(pointer:coarse)").matches && matchMedia("(pointer:fine)").matches// 沒有任何一種matchMedia("(pointer:none)").matches
所以,比較穩妥的判斷觸控螢幕的方法應該是這樣的:
function isTouchScreen(){ if(window.matchMedia){ // W3C way if(!matchMedia("(pointer:coarse)").matches && matchMedia("(pointer:fine)").matches){ return false } // Firefox way: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Media_queries#-moz-touch-enabled if(matchMedia("-moz-touch-enabled: 0").matches){ return false }}if(window.ontouchstart != null){ return true }}
2.zepto中的tap事件
[zepto touch事件來源碼]
地球人都知道zepto封裝的Touch事件都綁在了document上。於是問題接踵而至。
tap點擊穿透發生的條件:
1.兩個DOM節點一個在上一個在下;
2.兩個節點是父與子的關係;
3.同時綁定了tap事件;
4.如果下層元素是input元素的話,會觸發input元素獲得焦點(這時阻止冒泡,阻止瀏覽器的預設行為也有可能不同)。
解決辦法:
1.使用github上有一個叫做fastclick的庫;
2.監聽touchend事件,並在事件中使用preventDefault()阻止冒泡;
3.使用css3的pointer-events=true,pointer-events=none切換來實現;
4.延遲一定的時間來處理事件。
5.合理的改善dom結構,下層是否可以用a標籤作為連結處理,同是嘗試改善父子層的關係,合理的避免點擊穿透;
6.如果還不奏效,那麼就用click提代tap吧;
參考資料
[開發人員需要瞭解的WebKit]
[理解Webkit和Chromium:基於Chromium核心的Android WebView]
[理解WebKit和Chromium:Android 4.4 上的Chromium WebView]
[webkit百度百科]
[Chrom for Android 你必須知道的N件事]
[指尖下的JS(1)]
[指尖下的JS (2)]
[指尖下的JS (3)]
[android vs iPhone-touch Events]
[Touching and Gesturing on iPhone,Android and more]
[關於互動模式的媒體查詢]
移動端開發概覽【webview和touch事件】