前言

上周六,我将我们项目的click换成了tap事件,于是此事如梦魇一般折磨了我一星期!!!

经过我前仆后继的努力,不计代价的牺牲,不断的埋坑填坑,再埋坑的动作,最后悲伤的发现touch事件确实是个坑!

但是touch事件带来的用户感受提高对我们来说是一巨大进步,所以一些问题我们必须攻克,然在下已几近黔驴技穷,最后使出了浑身解数以一恶心的手段暂时压制其问题......

现在分享被折磨过程,希望对各位有所帮助

点击不起作用

我使用的源码不是最新的,zepto初始化时便为document.body绑定touchstart、touchmove、touchend事件

所以我们现在每一次在手机上的点击都会触发一次touch事件,由此可能引起的BUG:

每次手指触屏都会触发touchstart等事件,可能堵塞浏览器本身行为

由于我们是单页应用,初始化会为body设置height为100%,就算进入列表页或者其它,body页高度不会增加,于是就会出现不可点击现象!

以去哪儿为例

由于其城市列表为absolute,其它dom皆不显示从而导致body实际高度为0,那么此时如果为城市绑定tap事件的话,那么tap事件

在ios手机上不会有作用,电脑上有用,某些android无效

此问题较容易解决:

① 让body可伸缩,跟着元素扩展(不易实现)

② 将事件绑定至document(推荐)

tap特有的点透现象

地球人都知道tap会出现点透现象,我这里上一个代码给各位测试一番

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<style>
#list { border: 1px solid black; position: absolute; top: 0px; left: 10px; width: 200px; height: 100px; }
#d { border: 1px solid black; height: 300px; width: 100%; }
</style>
</head>
<body>
<div id="d">
<input type="text" id="input" style="width: 80px; height: 200px;" />
<div id="list">
</div>
</div>
</body>
<script src="res/libs/zepto.js" type="text/javascript"></script>
<script type="text/javascript">
window.log = function (msg) {
console.log(msg);
var div = $('#myMsg');
if (!div[0]) div = $('<div id="myMsg"></div>')
$('#d').append(div);
div.click(function () {
div.html('');
});
div.append($('<div>' + msg + '</div>'));
}
var list = $('#list');
var d = $('#d');
var input = $('#input'); input.tap(function (e) {
input.val(new Date().getTime());
}); list.tap(function (e) {
list.hide();
setTimeout(function () {
list.show();
}, 1000); }); d.tap(function () {
log('div tap');
});
</script>
</html>

这个页面有三个元素

① 父容器div,我们为他绑定了一个tap事件,会打印文字

② 在上的div,我们为其绑定了一个tap事件,点击便消失

③ input,主要用于测试focus问题

现在开启touch事件的情况下,我们点击上面的div,他会消失,于是:

div消失会触发div(list)的tap事件

div消失会触发input获取焦点事件

可能导致的项目BUG

以上问题可能导致些什么问题呢?

提示层一闪而过

我们可能会遇到这么一个场景:

表单提交页,用户提交时如果信息有误,会弹出一个提示,并且为蒙版添加click的关闭事件

但是有tap在的情况效果就不一样了,我们极有可能点击提交,弹出提示层,触发蒙版点击事件,蒙版关闭!!!

input获取焦点弹出键盘

我们可能遇到这种情况,我们在弹出层上做了一些操作后,点击弹出层关闭弹出层,但是下面有一个input(div有事件也行)

于是触发了div事件,于是input获取了焦点,某明奇妙的弹出来键盘!!!

BUG原因

以上问题是主要出现的问题,由此问题可能衍生出其它BUG,足以让我们苦不堪言!!!

但是引起这些问题的原因是什么呢???

先说冒泡

我们看zepto的touch事件源码,可以知道,我们一开始就将touchstart绑定到了document上,然后从e获取当前点击元素

完了触发touchend模拟tap等事件。

于是,首先我们想到了阻止冒泡是否可以解决问题:于是稍微修改下代码:

 list.tap(function (e) {
list.hide();
setTimeout(function () {
list.show();
}, 1000);
e.stopPropagation();
});

事实证明,阻止冒泡后div(d)的tap事件不会被触发,但是input的获取焦点问题依旧不能解决

至于原因,我这里也只能是猜测div(d)的触发是由于冒泡引起,而就算阻止冒泡阻止浏览器默认操作也不能阻止input获取焦点

神奇菊花解决问题

于是经过老夫不泄的努力,终于发现一个恶心的方法,可以暂缓此问题,他就是菊花!!!!

先上个代码:

 //该代码在zepto touch源码中
forTap = $('#forTap');
if(!forTap[0]) { forTap = $('<div id="forTap" style="background: black;color: White; display: none;
border-radius: 60px; position: absolute; z-index: 99999; width: 60px; height: 60px"></div>');
$('body').append(forTap);
} //touchstart
var el = touch.el; touch.isShowTap = false
while(el[0].nodeName != 'BODY'){
if(el.attr('lazyTap')) {
touch.isShowTap = true;
break;
}
el = el.parent();
} //touchend
var event = $.Event('tap')
event.cancelTouch = cancelAll touch.el.trigger && touch.el.trigger(event) if(touch.isShowTap) {
forTap.css({
top: (e.changedTouches[0].pageY - 30) + 'px',
left: (e.changedTouches[0].pageX - 30) + 'px'
})
forTap.show();
setTimeout(function () {
forTap.hide();
}, 350);
}

大家注意看代码,我现在为我们需要延迟的元素加一个lazyTap的属性

 <div id="d">
<input type="text" id="input" style =" width: 80px; height: 200px;"/>
<div id="list" lazyTap="true">
</div>
</div>

于是我们现在点击div(d)时候就会马上有一朵菊花移动到他下面

大家看到那个黑色的菊花了么???

这朵菊花会跟着被设置了lazyTap的属性触发了tap后便不会引发下面的事件,于是把菊花的背景去掉,他就是一个隐藏的菊花了。。。。。。

于是,到此为止吧!!!

结语

菊花带来的问题也有很大多,第一个就是不专业,第二个就是如果为li设置了lazyTap属性,那么在Ul上面绑定的事件会不会冒泡上去,我也没有验证!!

但是,按道理应该被触发,所以!!!如果您有什么更好的解决方案,请务必留意!!!

提升手持设备点击速度之touch事件带来的坑!的更多相关文章

  1. 手持设备点击响应速度,鼠标事件与touch事件的那些事

    前言 现在一直在做移动端的开发,这次将单页应用的网页内嵌入了app,于是老大反映了一个问题:app应用点击响应慢!我开始不以为然,于是拿着网页版的试了试,好像确实有一定延迟,于是开始了研究,最后选择了 ...

  2. 【读fastclick源码有感】彻底解决tap“点透”,提升移动端点击响应速度

    申明!!!最后发现判断有误,各位读读就好,正在研究中.....尼玛水太深了 前言 近期使用tap事件为老夫带来了这样那样的问题,其中一个问题是解决了点透还需要将原来一个个click变为tap,这样的话 ...

  3. 彻底解决TAP(点透)提升移动端点击响应速度

    使用fastclick 尼玛使用太简单了,直接一句: FastClick.attach(document.body); 于是所有的click响应速度直接提升,刚刚的!什么input获取焦点的问题也解决 ...

  4. 彻底解决tap“点透”,提升移动端点击响应速度

    申明!!!最后发现判断有误,各位读读就好,正在研究中.....尼玛水太深了 前言 近期使用tap事件为老夫带来了这样那样的问题,其中一个问题是解决了点透还需要将原来一个个click变为tap,这样的话 ...

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

    在触屏设备上,一些比较基础的手势都需要通过对 touch 事件进行二次封装才能实现.zepto 是移动端上使用率比较高的一个类库,但是其 touch 模块模拟出来的一些事件存在一些兼容性问题,如 ta ...

  6. Android Touch事件传递机制 二:单纯的(伪生命周期)

    转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...

  7. Android Touch事件传递机制 一: OnTouch,OnItemClick(监听器),dispatchTouchEvent(伪生命周期)

      ViewGroup View  Activity dispatchTouchEvent 有 有 有 onInterceptTouchEvent 有 无 无 onTouchEvent 有 有 有 例 ...

  8. H5案例分享:移动端touch事件判断滑屏手势的方向

    移动端touch事件判断滑屏手势的方向 方法一 当开始一个touchstart事件的时候,获取此刻手指的横坐标startX和纵坐标startY: 当触发touchmove事件时,在获取此时手指的横坐标 ...

  9. Android touch 事件传递机制

    前言: (1)在自定义view的时候经常会遇到事件拦截处理,比如在侧滑菜单的时候,我们希望在侧滑菜单里面有listview控件,但是我们希望既能左右滑动又能上下滑动,这个时候就需要对触摸的touch事 ...

随机推荐

  1. 插入排序java代码

    /** * 插入排序 * * 原理:从数组中取出一个值插入到一个左边已经排好序的数组片段中 * * @param a * @return */ public long[] InsertSort(lon ...

  2. java基础复习 - 自动装箱

    Integer a = 127; // 将整形127装箱对象 Integer b = 127; // 同上 System.out.print( a==b ); // true System.out.p ...

  3. 理解CSS中的数学表达式calc()

    前面的话 数学表达式calc()是CSS中的函数,主要用于数学运算.使用calc()为页面元素布局提供了便利和新的思路.本文将介绍calc()的相关内容 定义 数学表达式calc()是calculat ...

  4. javase基础复习攻略《六》

    学习JAVA的同学都知道,sun为我们封装了很多常用类,本篇就为大家总结一下我们经常使用的类.上一篇博客一位朋友留言问我String是不是引用数据类型?我通过查找资料发现String属于应用数据类型, ...

  5. Javaweb -- ServletContextListener

    当启动web应用后端服务时,有时需要预先从数据库或者配置文件等读取信息来配置一些全局变量之类的 这时可以用ServletContextListener,在启动服务时,加载设置基本配置 实现如下: (1 ...

  6. Oracle工具之DBNEWID

    DBNEWID是Oracle提供的一个用于修改数据库DBID和DBNAME的工具. 在引进该工具之前,如果我们想修改数据库的数据库名,必须重建控制文件.但即便如此,也无法修改该数据库的DBID.众所周 ...

  7. PHP内核的学习--PHP生命周期

    一切的开始: SAPI接口 SAPI(Server Application Programming Interface)指的是PHP具体应用的编程接口, 就像PC一样,无论安装哪些操作系统,只要满足了 ...

  8. Office英语学习好帮手

    Office提供了强大实用的英语学习助手,它可以自动翻译中英文,还可以显示详尽的解释帮助信息,当然标准的发音也是必不可少的.如何启动屏幕取词翻译功能呢?如何让office自动取词并翻译呢?如何收听单词 ...

  9. 【Swift学习】Swift编程之旅---类和结构体(十三)

    与其他编程语言所不同的是,Swift 并不要求你为自定义类和结构去创建独立的接口和实现文件.你所要做的是在一个单一文件中定义一个类或者结构体,系统将会自动生成面向其它代码的外部接口. 注意:通常一个类 ...

  10. [AngularJS] AngularJS系列(2) 中级篇之路由

    目录 原理 angular-route ui-router 事件 深度路由 原理 ng的route本质是监听hashchange事件. 在angular-route中 $rootScope.$on(' ...