一、click 和 tap 比较
两者都会在点击时触发,但是在手机WEB端,click会有 200~300 ms,所以请用tap代替click作为点击事件。
singleTap和doubleTap 分别代表单次点击和双次点击。
二、关于tap的点透处理
在使用zepto框架的tap来移动设备浏览器内的点击事件,来规避click事件的延迟响应时,有可能出现点透的情况,即点击会触发非当前层的点击事件。
处理方式:
(1)github上有一个叫做fastclick的库,它也能规避移动设备上click事件的延迟响应,https://github.com/ftlabs/fastclick将它用script标签引入页面(该库支持AMD,于是你也可以按照AMD规范,用诸如require.js的模块加载器引入),并且在dom ready时初始化在body上,如:
$(function(){
new
FastClick(document.body);
})
然后给需要“无延迟点击”的元素绑定click事件(注意不再是绑定zepto的tap事件)即可。
当然,你也可以不在body上初始化它,而在某个dom上初始化,这样,只有这个dom和它的子元素才能享受“无延迟”的点击。
实践开发中发现,当元素绑定fastclick后,click响应速度比tap还要快一点点
(2)为元素绑定touchend事件,并在内部加上e.preventDefault();
$demo.on('touchend',function(e){
// 改变了事件名称,tap是在body上才被触发,而touchend是原生的事件,在dom本身上就会被捕获触发
$demo.hide()
e.preventDefault();
// 阻止“默认行为”
})
三、touch事件touch是针对触屏手机上的触摸事件。现今大多数触屏手机webkit内核提供了touch事件的监听,让开发者可以获取用户触摸屏幕时的一些信息。
其中包括:touchstart,touchmove,touchend,touchcancel 这四个事件touchstart,touchmove,touchend事件可以类比于mousedown,mouseover ,mouseup的触发。
touchstart: 触摸开始的时候触发
touchmove: 手指在屏幕上滑动的时候触发
touchend: 触摸结束的时候触发
touchcancel:系统停止跟踪触摸时候会触发。当一些更高级别的事件发生的时候(如电话接入或者弹出信息)会取消当前的touch操作,即触发ontouchcancel。一般会在ontouchcancel时暂停游戏、存档等操作。
而每个触摸事件都包括了三个触摸列表,每个列表里包含了对应的一系列触摸点(用来实现多点触控):
touches: 当前位于屏幕上的所有手指的列表。
targetTouches: 位于当前DOM元素上手指的列表。
changedTouches: 涉及当前事件手指的列表。
每个触摸点由包含了如下触摸信息(常用):
identifier: 一个数值,唯一标识触摸会话(touch session
)中的当前手指。一般为从0开始的流水号。
target: DOM元素,是动作所针对的目标。
pageX/pageX/clientX/clientY/screenX/screenY: 一个数值,动作在屏幕上发生的位置(page包含滚动距离,client不包含滚动距离,screen则以屏幕为基准)。
radiusX/radiusY/rotationAngle: 画出大约相当于手指形状的椭圆形,分别为椭圆形的两个半径和旋转角度。(初步测试浏览器不支持,好在功能不常用,欢迎大家反馈。)
var obj = document.getElementByIdx_x('id');
obj.addEventListener('touchmove', function(event) {
// 如果这个元素的位置内只有一个手指的话
if (event.targetTouches.length == 1) {
event.preventDefault();// 阻止浏览器默认事件,重要
var touch = event.targetTouches[0];
// 把元素放在手指所在的位置
obj.style.left = touch.pageX-50 + 'px';
obj.style.top = touch.pageY-50 + 'px';
}
}, false);
但是单凭监听上面的单个事件,不足以满足我们去完成监听在触屏手机常见的一些手势操作,如双击、长按、左右滑动、缩放等手势操作。需要组合监听这些事件去封装对这类手势动作。
其实市面上很多框架都针对手机浏览器封装了这些手势,例如jqmobile、zepto、jqtouch,不过悲剧发生了,对于某些android系统,touchmove和touchend事件不能被很好的触发,举例子说明下:
比如手指在屏幕由上向下拖动页面时,理论上是会触发 一个 touchstart ,很多次 touchmove ,和最终的 touchend ,可是在android 4.0上,touchmove只被触发一次,触发时间和touchstart 差不多,而touchend直接没有被触发。
暂时我只发现在android 4.0会有这个bug,据说 iOS 3.x的版本也会有。
而显然jqmobile、zepto等都没有意识到这个bug对监听实现带来的严重影响,所以在直接使用这些框架的event时,或多或少会出现兼容性问题!
四、gesture事件
Gesture事件,包括手指点击(click),轻拂 (flick),双击(double-click),手指的分开、闭合(scale)、转动(rotate)等一切手指能在屏幕上做的事情,它只在有两根 或多根手指放在屏幕上的时候触发,事件处理函数中会得到一个GestureEvent类型的参数,它包含了手指的scale(两根移动过程中分开的比例) 信息和rotation(两根手指间连线转动的角度)信息。这个事件是对touch事件的更高层的封装,和touch一样,它同样包括 gesturestart,gesturechange,gestureend。gesture事件触发过程:Step 1、第一根手指放下,触发touchstartStep 2、第二根手指放下,触发gesturestartStep 3、触发第二根手指的touchstartStep 4、立即触发gesturechangeStep 5、手指移动,持续触发gesturechange,就像鼠标在屏幕上移动的时候不停触发mousemove一样Step 6、第二根手指提起,触发gestureend,以后将不会再触发gesturechangeStep 7、触发第二根手指的touchendStep 8、触发touchstart!注意,多根手指在屏幕上,提起一根,会刷新一次全局touch!重新触发第一根手指的touchstartStep 9、提起第一根手指,触发touchend