移动端开发概览【webview和touch事件】

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(混合模式移动应用).这是指介于web-app、native-app这两者之间的app,兼具“Native App良好用户交互体验的优势”和“Web App跨平台开发的优势”。
在我看来,这就是前端跟iOS开发和安卓开发一起做的事情嘛。它的实现就离不开WebView了,因为客户端需要渲染我提供的H5页面,那具体怎么实现呢?我也不知道了...去问客户端开发吧...

Touch事件

现在我们知道了手机跟手机不同,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 -相对于整个文档的坐标

[简单的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]

[关于交互模式的媒体查询]

from :http://www.cnblogs.com/skylar/p/mobile-webview-touch.html

时间: 2024-10-11 00:25:18

移动端开发概览【webview和touch事件】的相关文章

移动端触屏网页的touch事件

PC端网页从无到有发展至今,人们习惯了鼠标与键盘的人机交互模式,因此在PC端网页开发中一般使用鼠标事件和键盘事件. mouse事件: onclick事件:在单击鼠标左键或右键时发生. ondoubleclick事件:在双击鼠标左键时发生. onmousedown事件在单击鼠标按钮(左键.右键或中键)并且尚未松开时发生. onmousemove事件:在鼠标光标移动时发生. onmouseup事件:在松开鼠标按钮(左键.右键或中键)时发生. onmouseover事件:在鼠标光标移动到对象上时发生.

移动端开发用touch事件还是click事件

前端开发现在包含了跨浏览器,跨平台(不同操作系统)和跨设备(不同尺寸的设备)开发. 在移动开发的过程中,到底选取touch事件还是click事件?对了,请不要鄙视click,click在移动端开发用着也是不错的. 首先,我先说一下touch事件在开发中存在的两个问题: 1.touch事件在某些场景下存在点击穿透的问题. 2.touchstart事件时触摸屏幕就会触发,touchend事件是手指离开屏幕就会触发,而有时候,我们仅仅是只想滑动屏幕,却会触发这两个事件. 1问题的原因:移动端事件触发的

移动端 Touch 事件

在移动端页面开发时,常常会用到touch事件,比如左滑右滑的轮播等.常用的触摸事件有touchstart,touchmove,touchend. 每个事件包含下面三个用于跟踪虎摸的属性: touches:表示当前跟踪的触摸操作的touch对象的数组. targetTouches:特定于事件目标的Touch对象的数组. changeTouches:表示自上次触摸以来发生了什么改变的Touch对象的数组. 每个touch事件包含下面的属性: clientX:触摸目标在视口中的x坐标. clientY

移动端touch事件 || 上拉加载更多

前言: 说多了都是泪,在进行项目开发时,在上拉加载更多实现分页效果的问题上,由于当时开发任务紧急,所以就百度找了各种移动端的上拉下拉 实现加载更多的插件.然后就留下了个坑:上拉加载的时候会由于用户错误的姿势,例如长按后再touchmove等会出现卡死的假象.(ps:当然, 我不认为是插件的问题,当时的想法是觉得引用的插件存在冲突),于是,我就直接通过封装touch事件完成上拉加载实现分页的功能. 备注:文章最后会加上为实现这个功能我找的一些插件 了解touch事件 在应用touch事件实现上拉加

移动端开发注册、登陆input常用事件(input输入文字触发事件)

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>移动端开发注册.登陆input常用事件(input输入文字触发事件)</title> <meta name="keywords" content="

10-移动端开发教程-移动端事件

在前端的移动Web开发中,有一部分事件只在移动端产生,如触摸相关的事件.接下来给大家简单总结一下移动端的事件. 1. PC端事件在移动端的兼容问题 1.1 click事件的200~300ms延迟问题 由于移动端默认的布局视口宽度是980像素,所以网页文字非常小,为了快速让网页还原到原来的大小,Safari最新引入了双击缩放功能:用户双击手机页面的时候,浏览器会智能的缩放当前页面到原始大小. ?双击缩放的原理就是,当用户click一次之后,浏览器会经过约300ms之后检测是否再有一次click,如

javascript移动设备Web开发中对touch事件的封装实例

在触屏设备上,一些比较基础的手势都需要通过对 touch 事件进行二次封装才能实现.zepto 是移动端上使用率比较高的一个类库,但是其 touch 模块模拟出来的一些事件存在一些兼容性问题,如 tap 事件在某些安卓设备上存在事件穿透的 bug,其他类型的事件也或多或少的存在一些兼容性问题. 于是乎,干脆自己动手对这些常用的手势事件进行了封装,由于没有太多真实的设备来进行测试,可能存在一些兼容性问题,下面的代码也只是在 iOS 7.Andorid 4 上的一些比较常见的浏览器中测试通过. ta

移动端html touch事件

诸如智能手机和平板电脑一类的移动设备通常会有一(capacitive touch-sensitivescreen),以捕捉用户的手指所做的交互.随着移动网络的发展,其能够支持越来越复杂的应用,web开发者需要一种方法来处理这些事件.例如,几乎所有的快节奏游戏都需要玩家一次按下多个按钮,这种方式,在触摸屏情况下,意味着多点触摸. Apple在iOS 2.0中引入了触摸事件API,Android正迎头赶上这一事实标准,缩小差距.最近一个W3C工作组正合力制定这一触摸事件规范. 在本文深入研究iOS和

移动端touch事件影响click事件以及在touchmove添加preventDefault导致页面无法滚动的解决方法

这两天自己在写一个手机网页,用到了触屏滑动的特效,就是往右滑动的时候左侧隐藏的菜单从左边划出来. 做完之后在手机原生浏览器中运行正常,但在QQ和微信中打开,发现touchmove只会触发一次,而且touchend也经常不触发. 之后百度了一下这个问题,原因是 主要是由于200ms超时导致内核不一定会一直处理touchmove事件,一旦超时会将后续所有的事件转交给UI处理,导致touchmove不会一直触发. 为了解决开发者需要,建议开发者在touchstart时调用event.preventDe