转载自:http://www.jianshu.com/p/6e2b68a93c88

一、移动端300ms点击延迟

一般情况下,如果没有经过特殊处理,移动端浏览器在派发点击事件的时候,通常会出现300ms左右的延迟。也就是说,当我们点击页面的时候移动端浏览器并不是立即作出反应,而是会等上一小会儿才会出现点击的效果。在移动WEB兴起的初期,用户对300ms的延迟感觉不明显。但是,随着用户对交互体验的要求越来越高,现今,移动端300ms的点击延迟逐渐变得明显而无法忍受。

那么,移动端300ms的点击延迟是怎么来的呢?

问题由来
这要追溯至 2007 年初。苹果公司在发布首款 iPhone 前夕,遇到一个问题:当时的网站都是为大屏幕设备所设计的。于是苹果的工程师们做了一些约定,应对 iPhone 这种小屏幕浏览桌面端站点的问题。

这当中最出名的,当属双击缩放(double tap to zoom),这也是会有上述 300 毫秒延迟的主要原因。

双击缩放,顾名思义,即用手指在屏幕上快速点击两次,iOS 自带的 Safari 浏览器会将网页缩放至原始比例。 那么这和 300 毫秒延迟有什么联系呢? 假定这么一个场景。用户在 iOS Safari 里边点击了一个链接。由于用户可以进行双击缩放或者双击滚动的操作,当用户一次点击屏幕之后,浏览器并不能立刻判断用户是确实要打开这个链接,还是想要进行双击操作。因此,iOS Safari 就等待 300 毫秒,以判断用户是否再次点击了屏幕。 鉴于iPhone的成功,其他移动浏览器都复制了 iPhone Safari 浏览器的多数约定,包括双击缩放,几乎现在所有的移动端浏览器都有这个功能。之前人们刚刚接触移动端的页面,在欣喜的时候往往不会care这个300ms的延时问题,可是如今touch端界面如雨后春笋,用户对体验的要求也更高,这300ms带来的卡顿慢慢变得让人难以接受。

也就是说,移动端浏览器会有一些默认的行为,比如双击缩放、双击滚动。这些行为,尤其是双击缩放,主要是为桌面网站在移动端的浏览体验设计的。而在用户对页面进行操作的时候,移动端浏览器会优先判断用户是否要触发默认的行为。

那有什么办法可以解决这个问题呢?

浏览器开发商的解决方案

浏览器开发商要对移动端浏览器本身的设计进行改善,以提供长远的解决方案。

目前,浏览器开发商的解决方案主要有一下三种方案:
方案一:禁用缩放
当HTML文档头部包含如下meta标签时:

<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1,maximum-scale=1">

表明这个页面是不可缩放的,那双击缩放的功能就没有意义了,此时浏览器可以禁用默认的双击缩放行为并且去掉300ms的点击延迟。
这个方案有一个缺点,就是必须通过完全禁用缩放来达到去掉点击延迟的目的,然而完全禁用缩放并不是我们的初衷,我们只是想禁掉默认的双击缩放行为,这样就不用等待300ms来判断当前操作是否是双击。但是通常情况下,我们还是希望页面能通过双指缩放来进行缩放操作,比如放大一张图片,放大一段很小的文字。

方案二:更改默认的视口宽度
一开始,为了让桌面站点能在移动端浏览器正常显示,移动端浏览器默认的视口宽度并不等于设备浏览器视窗宽度,而是要比设备浏览器视窗宽度大,通常是980px。我们可以通过以下标签来设置视口宽度为设备宽度。

<meta name="viewport" content="width=device-width">

因为双击缩放主要是用来改善桌面站点在移动端浏览体验的,而随着响应式设计的普及,很多站点都已经对移动端坐过适配和优化了,这个时候就不需要双击缩放了,如果能够识别出一个网站是响应式的网站,那么移动端浏览器就可以自动禁掉默认的双击缩放行为并且去掉300ms的点击延迟。如果设置了上述meta标签,那浏览器就可以认为该网站已经对移动端做过了适配和优化,就无需双击缩放操作了。
这个方案相比方案一的好处在于,它没有完全禁用缩放,而只是禁用了浏览器默认的双击缩放行为,但用户仍然可以通过双指缩放操作来缩放页面。

方案三:CSS touch-action
网上很多文章把这个方案归结为指针事件,这令我很疑惑。

以我的理解来看,指针事件的提出并不是为了解决300ms点击延迟的,而是为了使用一个单独的事件模型,对鼠标、触摸、触控等多种输入类型进行统一的处理。也就是说,移动浏览器不用再为不同的输入设备设计不同的事件,网页的开发者也不用再为不同输入类型的设备写不同的事件响应代码,而是通过统一的指针事件就可以开发出跨不同输入类型终端的应用。

跟300ms点击延迟相关的,是touch-action这个CSS属性。这个属性指定了相应元素上能够触发的用户代理(也就是浏览器)的默认行为。如果将该属性值设置为touch-action: none,那么表示在该元素上的操作不会触发用户代理的任何默认行为,就无需进行300ms的延迟判断。

而设置这个CSS属性与否,指针事件应该都是可以工作的。所以,网上的文章令我很疑惑,希望有大神能给我指示~ 。。~

现有的解决方案

要解决300ms点击延迟的问题,从长远来说,自然还是得浏览器开发商提供统一的最终的解决方案。但是,到目前为止,以上三种方案并不能提供很好的兼容性,对于方案一和方案二,Chrome是率先支持的,Firefox紧随其后,然而令Safari头疼的是,它除了双击缩放还有双击滚动操作,如果采用这种两种方案,那势必连双击滚动也要一起禁用;对于方案三,IE是支持的,但是其他浏览器支持不完善。具体请看这篇文章:移动端Click300毫秒点击延迟的来龙去脉(转)

所以,在浏览器开发商最终统一的解决方案出来之前,我们还有一些基于Javascript的现成的解决方案可以用。

方案一:指针事件的polyfill
现在除了IE,其他大部分浏览器都还不支持指针事件。有一些JS库,可以让我们提前使用指针事件,比如

然而,我们现在关心的不是指针事件,而是与300ms延迟相关的CSS属性touch-action。由于除了IE之外的大部分浏览器都不支持这个新的CSS属性,所以这些指针事件的polyfill必须通过某种方式去模拟支持这个属性。一种方案是JS去请求解析所有的样式表,另一种方案是将touch-action作为html标签的属性。

方案二:FastClick
FastClick 是 FT Labs 专门为解决移动端浏览器 300 毫秒点击延迟问题所开发的一个轻量级的库。FastClick的实现原理是在检测到touchend事件的时候,会通过DOM自定义事件立即出发模拟一个click事件,并把浏览器在300ms之后的click事件阻止掉。

二、点击穿透问题

说完移动端点击300ms延迟的问题,还不得不提一下移动端点击穿透的问题。可能有人会想,既然click点击有300ms的延迟,那对于触摸屏,我们直接监听touchstart事件不就好了吗?
使用touchstart去代替click事件有两个不好的地方。
第一:touchstart是手指触摸屏幕就触发,有时候用户只是想滑动屏幕,却触发了touchstart事件,这不是我们想要的结果;
第二:使用touchstart事件在某些场景下可能会出现点击穿透的现象。

什么是点击穿透?
假如页面上有两个元素A和B。B元素在A元素之上。我们在B元素的touchstart事件上注册了一个回调函数,该回调函数的作用是隐藏B元素。我们发现,当我们点击B元素,B元素被隐藏了,随后,A元素触发了click事件。

这是因为在移动端浏览器,事件执行的顺序是touchstart > touchend > click。而click事件有300ms的延迟,当touchstart事件把B元素隐藏之后,隔了300ms,浏览器触发了click事件,但是此时B元素不见了,所以该事件被派发到了A元素身上。如果A元素是一个链接,那此时页面就会意外地跳转。

移动端点击300ms延迟的更多相关文章

  1. 移动端点击300ms延迟问题

    移动端点击延迟事件 1. 移动端浏览器在派发点击事件的时候,通常会出现300ms左右的延迟 2. 原因: 移动端的双击会缩放导致click判断延迟 解决方式 1. 禁用缩放 `<meta nam ...

  2. 【移动端】300ms延迟以及点透事件原因以及解决方案

    产生原因 移动端会有双击缩放的这个操作,因此浏览器在click之后要等待300ms,看用户有没有下一次点击,也就是这次操作是不是双击 说完移动端点击300ms延迟的问题,还不得不提一下移动端点击穿透的 ...

  3. 移动端300ms延迟解决的几种方法;

    方案一:禁用缩放 当HTML文档头部包含如下meta标签时: <meta name="viewport" content="user-scalable=no&quo ...

  4. 移动端300ms延迟问题和点击穿透问题

    一.移动端300ms延迟问题: 一般情况下,如果没有经过特殊处理,移动端浏览器在派发点击事件的时候,通常会出现300ms左右的延迟.也就是说,当我们点击页面的时候移动端浏览器并不是立即作出反应,而是会 ...

  5. 移动端点击事件300ms延迟问题解决方案——fastclick.js

    移动端点击事件300ms延迟的问题由来已久,如下截图 下面截图来自原文:https://www.jianshu.com/p/6e2b68a93c88 网上关于300ms延迟问题的解决方法,大致分为 3 ...

  6. 函数节流及手机端点击延迟200ms解决方法

    不论是H5开发还是微信小程序,手机端点击都会有300ms的延迟,在实际项目中,会到此频繁触发,如有接口会频繁的请求接口,除了会引起不必要的多次请求还会导致数据有问题.下面有二种方式来处理这个问题: 1 ...

  7. 移动端点击(click)事件延迟问题的产生与解决方法

    http://blog.csdn.net/xjun0812/article/details/64919063 问题的发现 上班做项目的时候碰到一个移动端项目,其中有个小游戏,相当于天上掉馅饼,用户需要 ...

  8. 移动端的300ms延迟和点击穿透

    移动端300ms延迟:假定这么一个场景.用户在 浏览器里边点击了一个链接.由于用户可以进行双击缩放或者双击滚动的操作,当用户一次点击屏幕之后,浏览器并不能立刻判断用户是确实要打开这个链接,还是想要进行 ...

  9. 移动端click事件300ms延迟

    移动端click 事件延迟300ms 一般情况下,如果没有经过特殊处理,移动端浏览器在派发点击事件的时候,通常会出现300ms左右的延迟.也就是说,当我们点击页面的时候移动端浏览器并不是立即作出反应, ...

随机推荐

  1. [转帖] sparkdev 的 博客 systemd

    从 init 系统说起 https://www.cnblogs.com/sparkdev/p/8448237.html systemd的内容 需要学习下. linux 操作系统的启动首先从 BIOS ...

  2. python 按照固定长度分割字符串

    >>> import re >>> string = '123456789abcdefg' >>> re.findall(r'.{3}', str ...

  3. jmeter之 jp@gc - Stepping Thread Group

    1.   安装好插件 参考文档“扩展Jmeter插件获取更多监听器” 2.   添加线程组 右键测试计划->添加->Threads(Users)->jp@gc - Stepping ...

  4. 一本通1640C Looooops

    1640:C Looooops 时间限制: 1000 ms         内存限制: 524288 KB [题目描述] 原题来自:CTU Open 2004 对于 C 语言的 for (variab ...

  5. office2013 激活方式

    1.下载   KMSpico_setup 2.关闭所有杀毒 3.打开  KMSpico_setup.exe 安装,下一步下一步,完成 4.打开word2013看下还有没弹出过期,没有即成功 5.卸载k ...

  6. Spring中ClassPathXmlApplication与FileSystemXmlApplicationContext的区别以及ClassPathXmlApplicationContext 的具体路径

    一.ClassPathXmlApplicationContext 的具体路径 String s[] = System.getProperty("java.class.path"). ...

  7. 【BZOJ1047】[HAOI2007]理想的正方形(单调队列,动态规划)

    [BZOJ1047][HAOI2007]理想的正方形(单调队列,动态规划) 题面 BZOJ 洛谷 题解 直接一个单调队列维护一下没给点和它前面的\(n\)个位置的最大值,再用一次单调队列维护连续\(n ...

  8. luogu1525 [NOIp2011]关押罪犯 (并查集)

    先从大到小排序,看到哪个的时候安排不开了 给每个人拆成两个,如果x和y有矛盾,就给x和y‘.y和x’连边:如果a和b(或a'和b')在同一个集合里,说明他们一定要在同一个监狱里. #include&l ...

  9. SSIS系列文章收藏

    http://blog.csdn.net/kk185800961/article/details/12398667 https://wenku.baidu.com/view/d16105abdd338 ...

  10. 使用 SP_OAXXX 创建文件夹,注意区别于 xp_cmdshell --mkdir xxx

    sp_configure 'show advanced options',1 go reconfigure with override go sp_configure 'Ole Automation ...