我在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