移动端touch、click、tap的区别


0311lc.com说:

一、click 与tap比较

click与tap都会出发点击事件,但是在手机web端,click会有200-300ms延迟,所以一般用tap(轻击)代替click作为点击事件。singleTap 和 doubleTap分别代表单击和双击。

二、使用tap会出现点透事件(事件穿透)

很多用过Zepto(移动端开发的库)都说使用tap会出现点透事件。

1、什么是tap事件穿透

执行完上层绑定的tap事件后,下层如果绑定着click事件或者本身就存在点击事件(a/input)也会默认触发,这就是点透事件,

2、出现点透事件的原因

首先要知道tap事件是通过监听绑定document上的touch事件来模拟的,并且tap 事件是冒泡到document上才出发的;

touchstart:在这个dom上用手触摸就能开始

click:在这个dom上用手触摸,且手指未曾移动,且在这个dom上手指离开屏幕,且触摸和离开时间很短(有的浏览器可能不检测时间间隔,照样可以出发click),才开始触发。

也就是说在移动端的事件触发从早到晚排序:touchstart touchstop  click。所以click的触发是有延时的,大约300ms,所以click触发的原则是,触发当前有click的元素,且该元素面朝用户的最前端,才会触发click。

3、解决办法

(1)github上有一个叫做fastclick的库https://github.com/ftlabs/fastclick

在dom ready时初始化在body上,如:

$(function(){
    newFastClick(document.body);
})

然后给需要“无延迟点击”的元素绑定click事件即可。实战开发中,click响应速度比tap还要快一点。

(2)为元素绑定touchend事件,并在内部加上e.preventDefault();

$A.on('touchend',function(e){//而touchend是原生的事件,在dom本身上就会被捕获触发
 
    $demo.hide()
    e.preventDefault();
 
})

监听touchend事件,阻止A元素的touchend的默认行为,从而阻止click事件的产生.

三、touch事件

主要有

touchstart事件:当手机触摸屏幕时触发,即使已经有一个手指放在屏幕上也会触发。

touchmove事件:当手指在屏幕上华东法人时候连续地触发。在这个事件发生期间,调用preventDefault()事件可以阻止滚动。

touchend事件:当手指从屏幕上离开的时候触发。

touchcancel事件:当系统停止跟踪触摸的触发。关于这个实际的确切触发时间。

每个触摸事件都包括了三个触摸列表:

1.touches:当前位于屏幕上的所有手指的一个列表。

2.targetTouches:位于当前DOM元素上的手指的一个列表。

3.changedTouches:涉及当前事件的手指的一个列表。

例如,在一个touchend事件中,这就会是移开的手指。

这些列表由包含了触摸信息的对象组成:

1.identifier:一个数值,唯一标识触摸会话(touchsession)中的当前手指。

2.target:DOM元素,是动作所针对的目标。

3.客户/页面/屏幕坐标:动作在屏幕上发生的位置。

4.半径坐标和rotationAngle:画出大约相当于手指形状的椭圆形。

================================================================

问题1:移动端click事件会延迟响应

Solution: 移动端使用zeptojs中的tap事件来替换click


问题2: tap事件有点透的问题存在

点透:点击上一层按钮的事件,会触发下一层的点击事件或者链接

Solution: 因为tap事件的实现原理就是通过touch事件。因此,我们可以通过touch事件的结合来模拟点击事件。

Element.on('touchstart', function() {})
.on('touchmove', function() {})
.on('touchend', function() {})
上述方式类似于mousedown + mousemove + mouseup的结合使用。

当然可以直接使用touchend,但是touchend 的问题在与如果从其他区域滑动到绑定事件的元素上,然后离开,也会触发touchend,因此这里存在用户体验很奇怪的问题,所以要根据需求结合使用。


问题3: 有的时候,一个页面需要在移动端和pc端同时使用,但是不能同时绑定click与touchend,因为这样会在移动端触发两次。

Solution: 通过判断是否存在于移动端,分别绑定相应的事件

// 点击之后执行什么内容
function foo(event){};
// 判断浏览器是否是移动端
function isMobile() {
return navigator.userAgent.match(/(iphone|ipad|ipod|ios|android|mobile|blackberry|iemobile|mqqbrowser|juc|fennec|wosbrowser|browserng|Webos|symbian|windows phone)/i);
}
//封装一个tap事件
function tap(ele, callback) {
var tag = 0;
if (isMobile()) {
$(ele).on('tuochstart', function(event) {
event.preventDefault();
tag = 0;
// 如果移动了,则不算tap,这一点和click处理有一些区别
}).on('touchmove', function() {
tag = 0;
}).on('touchend', function(event) {
if (tag == 0) {
callback(event);
}
})
} else {
$(ele).on('click', function(event) {
callback(event);
})
}
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注