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

Touch事件

现在我们知道了手机跟手机不同,WebKit与WebKit的不同,先知道着,我先从头看一下touch事件,再看看他会有什么问题。

Touch事件:

 touchstart:当一个手指放在屏幕上时触发;
touchend:当一个手指从屏幕上移走的时候触发;
touchmove:当一个手指已经在屏幕上并且在屏幕上移动时触发;
touchcancel:如果太多个手指在屏幕上或一个其他动作发生时触发。

Touch事件中事件对象的属性:

 touches: 它包含了每个手指当前touch屏幕的一系列信息;
targetTouches: 像touches一样,但是提供当前手指的touch信息;
changedTouches: 包含每一个手指的touch改变的信息。

怎么理解呢:
  1. 当你放下一个手指的时候,上面三个属性会提供相同的信息;
  2. 当你放下第二个手指的时候,touches对象会包含两条信息,每个手指都有一个;targetTouches只有在第二根手指放在了同第一根手指相同的节点上的时候会包含两条信息(否则的话它只包含第二根手指的信息);changedTouches只会包含跟第二根手指相关的信息.
  3. 如果几乎同是两个手指触碰屏幕,在changedTouches中会有两个手指的信息。
  4. 如果我们在屏幕上移动手指,唯一会改变的对象是changedTouches,它会包含我们移动的一个或两个手指的信息;
  5. 如果抬起一个手指,它的信息会从touches和targetTouches对象中移除,但是在changedTouches会找到它的信息;
  6. 当我们把最后一个手指从屏幕上移走,touches和targetTouches对象会为空了,但是changedTouches将会保留最后这跟手指的信息。

touches对象中包含的每个手指的信息列表中也有下面这些我们在鼠标事件中熟悉的属性:

 identifier - 一个标识符,对于每个touch点(手指)是独一无二的;
target -当前手指touch的dom节点;
clientX/clientY -touch事件发生时相对视口(viewport)的坐标(包含滚动)
screenX/screenY -相对于屏幕的坐标
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:

 None,当前设备没有任何除键盘或触控板之外的输入方式
Fine,当前设备使用了鼠标来操作
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事件】的更多相关文章

  1. Xamarin开发笔记—WebView双项事件调用

    1.Xamarin调用WebView: 原理:Xamarin.Forms WebView内置方法xx.Eval(..)可以调用到页面里面的js函数. WebView展示的代码如下: var htmlS ...

  2. ios-cocos2d游戏开发基础-CCLayer和Touch事件-开发笔记

    有时候在同一个场景里你需要多个CCLayer.你可以参照以下代码生成这样的场景 +(id) scene { CCScene* scene = [CCScene node]; CCLayer* back ...

  3. 移动端touch事件实现页面弹动--小插件

    动手之前的打盹 说实话真的是好久没有更新博客了,最近一直赶项目,身心疲惫:最关键的是晚上还要回去上一波王者,实在是忙啊! 这周下来,清闲了些许,或许是因为要到国庆的缘故吧,大家都显得无精打采.俗话说的 ...

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

    前端开发现在包含了跨浏览器,跨平台(不同操作系统)和跨设备(不同尺寸的设备)开发. 在移动开发的过程中,到底选取touch事件还是click事件?对了,请不要鄙视click,click在移动端开发用着 ...

  5. Touch事件在移动端web开发中的详解

    一.pc端事件回顾 HTML事件.DOM0事件.DOM2事件 事件对象. 如果上述概念不清楚,请先去了解. 二.移动端事件简介 2.1 pc端事件在移动端的问题 ​ 移动设备主要特点是不配备鼠标,键盘 ...

  6. 移动端 js touch事件

    随着智能手机和平板电脑的普及, 越来越多的人用移动设备浏览网页,我们平时在pc浏览器上用的鼠标事件,比如:click, mouseover等, 已经无法满足移动设备触摸屏的特点,触摸时代的到来,离不开 ...

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

    前言: 说多了都是泪,在进行项目开发时,在上拉加载更多实现分页效果的问题上,由于当时开发任务紧急,所以就百度找了各种移动端的上拉下拉 实现加载更多的插件.然后就留下了个坑:上拉加载的时候会由于用户错误 ...

  8. 从零开始学 Web 之 移动Web(五)touch事件的缺陷,移动端常用插件

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  9. 移动端click时间、touch事件、tap事件

    一.click 和 tap 比较 两者都会在点击时触发,但是在手机WEB端,click会有 200~300 ms,所以请用tap代替click作为点击事件. singleTap和doubleTap 分 ...

随机推荐

  1. 5-2 bash 脚本编程之一 变量、变量类型等

    1. bash变量类型 1. 环境变量 2. 本地变量(局部变量) 3. 位置变量 4. 特殊变量 2. 本地变量 VARNAME=VALUE, 整个bash进程 3. 环境变量 作用域为当前shel ...

  2. 关于selenium RC的脚本开发

    第一.需要录制脚本,找个我也不说了.就是在firefox下下载一个selenium-IDE并且安装. 第二.在工具里找到selenium-IDE点击运行. 第三.默认是红色按钮点击状态的,接下来随便你 ...

  3. 第10章 Shell编程(1)_正则表达式

    1. 基础的正则表达式 1.1 正则表达式与通配符 (1)正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配.grep.awk.sed等命令可以支持正则表达式. (2)通配符用来匹配符合条件的 ...

  4. HOLOLENS 扫描特效 及得出扫描结果(SurfacePlane)

    HOLOLENS 扫描特效 及得出扫描结果(SurfacePlane) 要求只扫出地板和墙, 由于地板和墙面积较大 扫描结果 HOLOTOOLKIT老版本点在参数调节PlaneFinding.Find ...

  5. winform 用户控件、 动态创建添加控件、timer控件、控件联动

    用户控件: 相当于自定义的一个panel 里面可以放各种其他控件,并可以在后台一下调用整个此自定义控件. 使用方法:在项目上右键.添加.用户控件,之后用户控件的编辑与普通容器控件类似.如果要在后台往窗 ...

  6. Django基础之wsgi

    Django 一 什么是web框架 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演 ...

  7. libsvm的数据格式及制作

    1.libsvm数据格式 libsvm使用的训练数据和检验数据文件格式如下: [label] [index1]:[value1] [index2]:[value2] … [label] [index1 ...

  8. C#将WebBowser控件替换为Chrome内核

    摘要 由于最近要做一个浏览器式的软件,其中有不少地方需要使用到jQuery和BootStrap,但是在C#中,默认的WebBrowser控件默认使用的是IE的core,而低版本的IE在JS加载上总是容 ...

  9. 实现数据库的跨库join

    功能需求 首先要理解原始需求是什么,为什么要跨库join.举个简单的例子,在日志数据库log_db有一份充值记录表pay_log,里面的用户信息只有一个userid:而用户的详细信息放在主库main_ ...

  10. 用vue.js学习es6(四):Symbol类型

    一.Symbol类型: 1.ES6引入了一种新的原始数据类型Symbol,表示独一无二的值.它是JavaScript语言的第七种数据类型,前六种是:Undefined.Null. 布尔值(Boolea ...