我在webkit內核的chrome中進行開發的頁面,拿着iPhone和安卓機來進行測試,傳說中它們的瀏覽器內核也是WebKit,那麼問題來了,一樣的頁面爲何在ios中和安卓中表現不一樣,出現了各類稀奇古怪的bug...css
我嘗試找下二者的根本區別:html
- iOS
隨着2007年6月29日iPhone的上市,WebKit進入iPhone OS平臺,通過Apple的定製,成爲iPhone OS平臺獨一無二的排版引擎;前端
- Androidandroid
在舊版本的安卓中:ios
熟悉Android系統和HTML編程的人可能都據說過Android提供的一個重要類android.webkit.WebView,它繼承於View類,這是它同其它不少控件的類似之處。不一樣之處在於,它可以用來渲染網頁。當前,WebView的實現是基於現有的缺省WebKit內核(Android缺省瀏覽器是基於WebView構建),它不一樣於chromium所使用的WebKit內核,雖然它們都叫WebKit.css3
可是,在最新的Android 4.4 Kitkat版本中,本來基於Android WebKit的WebView實現被換成基於Chromium的WebView實現.git
- 結論github
因而可知,雖然它們都叫WebKit,可是WebKit和WebKit也是不一樣的:web
讀了這篇文章:[開發者須要瞭解的WebKit] 你就會了解到了,同是WebKit它也有不一樣的Port,它們專一於不一樣的部分,每一個WebKit port中有共享的部分,可是也有很大一部分功能是不會共享的,其中就包括JS引擎。chrome
因此我中止了說:「爲何ios都行了安卓怎麼就不行呢?」,而是埋頭開始修bug...雖然有時候這些bug不是那麼好修...
做爲一個前端兒,你確定聽過WebView這個詞兒。我也聽過,也好奇過,把個人網頁放到手機上看就叫WebView啦?WebView究竟是什麼呢?
其實WebView是類名或者說它是一個API(在我看來):
- 在Android中,這是個繼承於View類的類android.webkit.WebView,用來佈局和渲染網頁;
- 在iOS中,這個類叫UIWebView,一樣是應用程序的UI接口。
咱們前端怎麼就會對客戶端的類名這麼熟悉了呢?
若是你是個有見識的前端那麼你確定聽過Hybrid App(混合模式移動應用).這是指介於web-app、native-app這二者之間的app,兼具「Native App良好用戶交互體驗的優點」和「Web App跨平臺開發的優點」。
在我看來,這就是前端跟iOS開發和安卓開發一塊兒作的事情嘛。它的實現就離不開WebView了,由於客戶端須要渲染我提供的H5頁面,那具體怎麼實現呢?我也不知道了...去問客戶端開發吧...
如今咱們知道了手機跟手機不一樣,WebKit與WebKit的不一樣,先知道着,我先從頭看一下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 -相對於整個文檔的座標
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事件都綁在了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和Chromium:基於Chromium內核的Android WebView]
[理解WebKit和Chromium:Android 4.4 上的Chromium WebView]
[android vs iPhone-touch Events]
[Touching and Gesturing on iPhone,Android and more]
from :http://www.cnblogs.com/skylar/p/mobile-webview-touch.html