移动页面click延迟引发的touch问题
一、事件捕获与冒泡
先扯一下事件的触发流程,这个之后会用到。
DOM2级事件规定事件包括三个阶段:
① 事件捕获阶段
② 处于目标阶段
③ 事件冒泡阶段
大概的流程就是事件从最外层一层一层往里面传递(捕获阶段), 到达触发事件的目标元素(目标阶段),然后再一层一层往上冒泡(冒泡阶段)。这个流程事件所经过的元素绑定的对应事件的侦听器都会被触发。例如对元素p的子元素c绑定点击事件,点击元素c后会先在p触发点击事件,使用dispatch触发也是。
PS:事件侦听通过target.addEventListener(type, listener[, useCapture])添加,useCapture参数代表是否在捕获阶段触发事件。
二、click事件的300ms延迟
移动设备中使用click事件和在PC端会有所不同,大多数基于触摸的浏览器设备,在点击时都会有个300ms的事件触发等待时间,原因在于单击后面还有个双击缩放动作,这个涉及到触摸设备的手势交互行为原生设计,设备需要通过时间判断是单击还是双击。
对于这300ms的延迟,根据网上搜索的资料,可通过几个简单的方法解决:
- 无视之。。。如果所涉及业务对点击的反应时间要求不大,300ms其实是可以忽略的。
- 在 chrome 和 firefox 的移动版本中,禁用页面缩放可消除该延迟。不过只兼容这两种不好。
- 在 chrome 32+ 中,设置 viewport 的宽度小于或等于物理设备的宽度。因为只支持chrome 32+,所以也忽略。
- IE10+中设置CSS触摸 action 属性。以后其他浏览器可能也会支持。但目前只支持IE10+,所以也忽略。
- 使用touch事件而不是click事件。这样必须可以解决延迟,但也因此引发了奇怪的问题,由此转入正文。
三、zepto的tap事件
如果我们直接使用touchend事件来代替click事件,一个很明显的不妥就是如果滑动到某个元素上放开手那么就会触发该元素的touchend事件,这明显不跟点击操作一致。另外一个问题即触发touchend事件后,在该区域300ms后还会触发一次click事件,如果一个元素touchend后消失,那么其点击区域底下的元素还会被触发一次click事件,这个问题叫做点透,不过这可以通过event.preventDefault来阻止(默认行为)。
为了更好的模拟点击事件并解决移动设备点击的300ms延迟,zepto的touch模块自定义了一个tap事件,该事件原理即是使用touch事件来模拟的。基本原理就是给元素绑定touchstart和touchend事件,然后判断前后事件的触发区域是否一致,是的话即触发自定义的点击事件。
看起来挺完美的,但事实上使用zepto的tap事件即使在事件回调函数中使用了preventDefault还是会出现点透问题。究其原因,就是zepto在触发事件的时候使用了定时器。在自定义事件被触发之前默认行为早就发生了,因此阻止不了click事件的触发。
暂时不管zepto,对于click事件,我们可以用另外一个插件提高click事件的响应速度,这就是fastclick!
四、fastclick
Fastclick的基本思想就是在某个父元素上捕获其子元素的touchstart与touchend事件,然后依然根据位置信息判断是否为点击动作,如果是的话立即使用dispatchEvent手动派发子元素的click事件,从而缩短了响应事件,并且在touchend的时候使用preventDefault阻止默认事件,防止300ms后再次触发click事件。
事情貌似就这么解决了,但事实就是没这么完美。撇开手动派发事件带来的性能损耗不说,在android上preventDefault阻止touchend触发click事件还没有用,即在android上只要使用了touchend,就一定会触发click事件,翻阅了很多资料后发现这个问题无法解决,有人说touchstart的时候调用preventDefault可阻止click,但亲测过不行。
这时候,就只能用比较猥琐的方法来解决了。在fastclick判断为点击操作并触发click事件时,我们给事件对象添加一个flag。从之前的内容可以得知click事件会先在外层容器上触发,因此我们在根目录上侦听click事件,当事件对象存在flag时即不做操作,当不存在时即阻止其事件派发流程。这样即元素绑定在元素上的点击事件侦听器只会被手动触发的click事件触发。
document.addEventListener('click', function (event) { if (event.myclick == true) { return true; } if (event.stopImmediatePropagation) { event.stopImmediatePropagation(); } else { event.propagationStopped = true; } event.stopPropagation(); event.preventDefault(); return true; }, true);
虽然使用fastclick可以解决click的延迟问题,但添加了许多额外的操作,性能上的损耗是无可避免的。因此如果对点击操作的要求不是很高的话还是建议忽略那点延迟。
移动页面click延迟引发的touch问题的更多相关文章
- JS click延迟解决方案
click延迟解决方案 移动端click事件会有300ms的延迟,原因是移动端屏幕双击会缩放页面 1.禁止缩放功能 浏览器禁用默认双击缩放行为去掉300ms的点击延迟 user-scalabl ...
- 聊聊click延迟和点击穿透
博客原文地址:Claiyre的个人博客 https://claiyre.github.io/ 如需转载,请在文章开头注明原文地址 移动端click事件被延迟 移动端的开发经常需要监听用户的双击行为,所 ...
- zepto的touch模块解决click延迟300ms问题以及点透问题的详解
大家都知道移动端的click事件会延迟300ms触发,这时大家可以使用zepto的touch模块,里面定义了一个tap事件,通过绑定tap事件,可以实现点击立即触发的功能. 那么,它的tap事件是怎么 ...
- 移动端click延迟和tap事件
一.click等事件在移动端的延迟 click事件在移动端和pc端均可以触发,但是在移动端有延迟现象. 1.背景 由于早期移动设备浏览网页时内容较小,为了增强用户体验,苹果公司专门为移动设备设计了双击 ...
- AlloyTouch Button插件-不再愁click延迟和点击态
移动端不能使用click,因为click会有300ms.所有有了fastclick这样的解决方案.然后fastclick并没有解决点击态(用户点击的瞬间要有及时的外观变化反馈)的问题.hover会有不 ...
- 开发移动端web页面click事件失效问题
这两天在做一个WAP页面,在chrome上模拟移动端的时候,都好好的,然而放到手机上测试时, 发现有些点击事件直接无反应,但是有些有反应: 难道是由于我页面上有用到滚动插件,里面的touch事件的pr ...
- 由单页面web应用引发的企业应用问题
由于单页面web应用的流行,client与server端之间都对应的产生了一些微妙的变化,比方,client原来仅仅是用来展示页面和理清逻辑,而现在逐渐转变成了一个可以进入驱动状态的应用程序. 未来的 ...
- javascript js 完美解决 click 与 dblclick 冲突,并且不会导致click延迟
示例代码: marker.addEventListener("click", function(){ if (!window.markerClicked) { window.mar ...
- bug:页面交互操作引发的问题
最近在测试一些h5页面,突然悟到一些测试点 需求点: 用户可以在页面领取礼物,领取的礼物在页面底部展示,用户点击礼物可调起分享弹窗,礼物超过一屏可左右滑动, bug的表现形式: 仅当礼物超过一屏时(一 ...
随机推荐
- Oracle备份恢复之逻辑备份
exp 交互模式:导出scott用户下的emp表. [oracle@localhost ~]$ exp Export: Release 10.2.0.1.0 - Production on Thu N ...
- Thymeleaf模板引擎的初步使用
在springboot中,推荐使用的模板引擎是Thymeleaf模板引擎,它提供了完美的Spring MVC的支持.下面就简单的介绍一下Thymeleaf模板引擎的使用. 在controller层中, ...
- 2018/04/18 每日一学Linux 之 ssh关闭密码登录
在平常工作中,常常需要关闭 SSH 的密码登录,只留 SSH 证书登录. 好处显而易见,避免了经常输入密码导致的密码泄露,和设置密码导致被暴力破解的可能性. -- 方法也很简单,首先 你是可以 登录 ...
- Python性能鸡汤(转)
英文原文:http://blog.monitis.com/index.php/2012/02/13/python-performance-tips-part-1/ 英文原文:http://blog.m ...
- 易忘的mysql语句
1.修改主键 ALTER TABLE `resource` DROP PRIMARY KEY ,ADD PRIMARY KEY ( `rid` ) 2.加上auto_increment ) NOT N ...
- NYOJ 587 blockhouses 【DFS】
blockhouses 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描写叙述 Suppose that we have a square city with straigh ...
- mysql查看和修改注释
MySQL查看注释,MySQL修改注释,mysql查看注释,mysql修改注释 1.给大家做演示,这里随便创建一张学生表,代码如下: CREATE TABLE `student` ( `id` int ...
- (转)Kangle配置文件
kangle配置文件 (重定向自Kangle配置文件) 目录 [隐藏] 1配置文件介绍 2重新加载配置文件 3config 3.1request和response(配置访问控制) 3.2listen( ...
- excel用法
1:求大于某一值的个数:使用COUNTIF(区间,标准) 要大写 =COUNTIF(B2:B48,">=95") 2:求某一区间的个数用:大区间个数减小区间个数 =CO ...
- PAT 1032 Sharing[hash][链表][一般上]
1032 Sharing (25)(25 分) To store English words, one method is to use linked lists and store a word l ...