提升手持设备点击速度之touch事件带来的坑!

简介:
前言

上周六,我将我们项目的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会出现点透现象,我这里上一个代码给各位测试一番

 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3 <head>
 4     <title></title>
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
 6     <style>
 7         #list { border: 1px solid black; position: absolute; top: 0px; left: 10px; width: 200px; height: 100px; }
 8         #d { border: 1px solid black; height: 300px; width: 100%; }
 9     </style>
10 </head>
11 <body>
12     <div id="d">
13         <input type="text" id="input" style="width: 80px; height: 200px;" />
14         <div id="list">
15         </div>
16     </div>
17 </body>
18 <script src="res/libs/zepto.js" type="text/javascript"></script>
19 <script type="text/javascript">
20     window.log = function (msg) {
21         console.log(msg);
22         var div = $('#myMsg');
23         if (!div[0]) div = $('<div id="myMsg"></div>')
24         $('#d').append(div);
25         div.click(function () {
26             div.html('');
27         });
28         div.append($('<div>' + msg + '</div>'));
29     }
30     var list = $('#list');
31     var d = $('#d');
32     var input = $('#input');
33 
34     input.tap(function (e) {
35         input.val(new Date().getTime());
36     });
37 
38     list.tap(function (e) {
39         list.hide();
40         setTimeout(function () {
41             list.show();
42         }, 1000);
43 
44     });
45 
46     d.tap(function () {
47         log('div tap');
48     });
49 </script>
50 </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等事件。

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

1 list.tap(function (e) {
2     list.hide();
3     setTimeout(function () {
4         list.show();
5     }, 1000);
6     e.stopPropagation();
7 });
事实证明,阻止冒泡后div(d)的tap事件不会被触发,但是input的获取焦点问题依旧不能解决

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

神奇菊花解决问题

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

先上个代码:

 1 //该代码在zepto touch源码中
 2 forTap = $('#forTap');
 3 if(!forTap[0]) { forTap = $('<div id="forTap" style="background: black;color: White; display: none; 
 4 border-radius: 60px; position: absolute; z-index: 99999; width: 60px; height: 60px"></div>');
 5     $('body').append(forTap);
 6 }
 7 
 8 //touchstart
 9 var el = touch.el; touch.isShowTap = false
10 while(el[0].nodeName != 'BODY'){
11 if(el.attr('lazyTap')) {
12     touch.isShowTap = true;
13     break;
14     }
15 el = el.parent();
16 }
17 
18 //touchend
19 var event = $.Event('tap')
20 event.cancelTouch = cancelAll
21 
22 touch.el.trigger && touch.el.trigger(event)
23 
24 if(touch.isShowTap) {
25     forTap.css({
26         top: (e.changedTouches[0].pageY - 30) + 'px',
27         left: (e.changedTouches[0].pageX - 30) + 'px'
28     }) 
29     forTap.show();
30     setTimeout(function () {
31         forTap.hide();
32     }, 350);
33 }
大家注意看代码,我现在为我们需要延迟的元素加一个lazyTap的属性

1 <div id="d">
2     <input type="text" id="input"  style =" width: 80px; height: 200px;"/>
3     <div id="list" lazyTap="true">
4     </div>
5 </div>
于是我们现在点击div(d)时候就会马上有一朵菊花移动到他下面



 

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

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

于是,到此为止吧!!!

结语

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

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

 
本文转自叶小钗博客园博客,原文链接:http://www.cnblogs.com/yexiaochai/p/3391015.html如需转载请自行联系原作者

相关文章
|
关系型数据库 MySQL 测试技术
mysql中删除数据的几种方法
在MySQL数据库中,删除数据是一个常见的操作,它允许从表中移除不再需要的数据。在执行删除操作时,需要谨慎,以免误删重要数据。
679 3
|
机器学习/深度学习 数据可视化 网络架构
增强深度学习模型的可解释性和泛化能力的方法研究
【8月更文第15天】在深度学习领域,模型的准确率和预测能力是衡量模型好坏的重要指标。然而,随着模型复杂度的增加,它们往往变得越来越难以理解,这限制了模型在某些关键领域的应用,例如医疗诊断、金融风险评估等。本文将探讨如何通过几种方法来增强深度学习模型的可解释性,同时保持或提高模型的泛化能力。
1222 2
|
缓存 Nacos 数据库
nacos常见问题之日志一直报403如何解决
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
|
10月前
|
数据采集 人工智能 搜索推荐
|
11月前
|
机器学习/深度学习 算法 搜索推荐
深度学习之差分隐私
基于深度学习的差分隐私是一种在保护用户隐私的同时使用数据进行模型训练的技术。它的核心理念是通过加入随机噪声来隐藏个体数据的影响,防止在分析或模型训练过程中泄露个人信息。
1042 2
|
Java 测试技术 开发者
Java线程池ThreadPoolExcutor源码解读详解09-4种拒绝策略
本文介绍了线程池的四种拒绝策略:AbortPolicy、DiscardPolicy、DiscardOldestPolicy和CallerRunsPolicy,并通过代码示例展示了它们在任务过多时的不同处理方式。AbortPolicy会抛出异常并停止主线程;DiscardPolicy会默默丢弃新任务;DiscardOldestPolicy会抛弃队列中最旧的任务来接纳新任务;而CallerRunsPolicy则是由调用者线程执行被拒绝的任务,以减缓新任务的提交速度。这四种策略适用于不同的场景,开发者可以根据需求选择合适的策略。
1385 5
|
Linux 编译器
Linux交叉编译libunwind
Linux交叉编译libunwind
663 0
|
安全 Java C++
消灭“脑细胞杀手”,阿里专家带你深入C++对象的生命周期管理
C/C++的指针一直是令人又爱又恨的特性。围绕指针产生了许许多多优雅的数据结构和系统实现,但又滋生了不少“脑细胞杀手”——内存Bug。如何通过指针管理C++中对象,如何管理对象的生命周期呢?本文中,阿里巴巴高级开发工程师付哲就为大家分享《C++对象的生命周期管理》。
5986 0
|
自然语言处理 索引
技术写作最佳实践与策略指南
作为一名技术写作者,遵守既定的最佳实践有助于确保您的工作的一致性、清晰性和整体质量。一些常见的最佳实践包括: 始终考虑受众: 牢记用户视角编写内容。确保技术术语、语言和复杂程度与您的目标读者相匹配。 逻辑地组织内容: 将材料分为章节、子章节、项目符号列表和表格。使用标题帮助读者浏览内容。 必要时使用图表和图像: 视觉辅助工具通常可以提高对复杂概念或过程的理解。 写出清晰简洁的句子: 避免使用读者可能不明白的模糊信息和术语。始终追求可读性。 编辑、编辑、编辑: 校对您的工作,纠正语法和拼写错误,并确保信息准确且最新。 遵循这些最佳实践可以提高您的技术写作效率,并确保您的受众能够轻松理
1354 0