一、什么是ios的300ms点击延时问题

ios的移动端页面对点击事件有300ms延时。

二、为什么存在这个问题

这要追溯至 2007 年初。苹果公司在发布首款 iPhone 前夕,遇到一个问题 —— 当时的网站都是为大屏幕设备所设计的。于是苹果的工程师们做了一些约定,应对 iPhone 这种小屏幕浏览PC端站点的问题。这当中最出名的,当属双击缩放(double tap to zoom)。

双击缩放,顾名思义,即用手指在屏幕上快速点击两次,iOS 自带的 Safari 浏览器会将网页缩放至原始比例。

那么问题来了,假设用户在 iOS Safari 里边点击了一个链接,当用户一次点击屏幕之后,浏览器并不能立刻判断用户是确实要打开这个链接,还是想要进行双击操作。

因此,iOS Safari 就等待 300 毫秒,以判断用户是否再次点击了屏幕。

三、这是一个问题吗

上文的假设场景看起来没毛病,那么,这是一个问题吗?

回答:是。

如今是个移动端开发的 web 应用性能可以同原生应用匹敌的时代,所有的单击事件都有 300 毫秒延迟,必然是不可接受的。

四、验证问题

虽说各种资料均表明ios移动端页面click事件有300ms延时,然而我还是想看一下到底有多少延时,虽然感觉是慢了点,但是,用数据说话更加可信。代码如下:

然后在iphone里面打开测试页面:

点击按钮,显示延时,发现延时分布在370ms左右,比传说的300ms要大,这和设备有关。

五、如何解决问题

问题真实存在,那么就需要解决问题。

1、移动端一般都用了类jq的库——zepto,zepto封装了一系列的触摸事件,其中的tap事件就是click事件去掉300ms延时的事件,然而,zepto的tap事件有一个点透的问题,故该方案不可行。

2、使用fastclick库。

六、fastclick

我比较懒,简介扣了人家的自我介绍:

兼容性也很好:

用法也很简单,这里我就不说了,只需要注意一点:使用FastClick的时候,在需要使用的层上,实例化它。我们使用document.body是因为希望所有的按钮和链接都获得快速点击。

来个使用后的效果图:

七、思考

1、为什么zepto的tap事件会点透,而fastclick的click事件不会点透?

我们先来了解下什么叫点透问题。假如你在列表页面上创建一个弹出层,弹出层有个关闭的按钮(绑定了tap事件),你点了这个按钮关闭弹出层后,这个按钮正下方的内容也会执行点击事件(或打开链接)。这个就是一个“点透”现象。

点透出现的原因是:延迟300ms的click事件触发了。

zepto的touch模块中,没有对这个延迟300ms的click事件取消,或者取消不了。而fastClick中,会对这个延迟300ms的click事件取消,也就是这个click事件不会触发。

所以zepto的tap事件(通过touchstart和touchend模拟出来的)有点透问题,而fastClick的click事件(通过touchstart和touchend模拟出来的)没有。

深入到zepto的touch.js和fastClick的源码,我们可以得知:zepto的tap事件和fastClick的click事件,源码差不多。为什么基本相同的代码,zepto会点透而fastclick不会呢?原因是zepto的代码里面有个settimeout,在settimeout里面执行e.preventDefault()不会生效,因此zepto中的延迟300ms的click事件会触发,而fastClick不会。

2、为什么不能用touchend代替click来解决延时问题?

一种解决办法是,用touchend替代click,然后preventDefault来阻止默认行为click。

听起来简单易行,然而功能复杂的时候就会出问题,比如滑动加选择,会因为滑动触发touchend,从而触发选择行为。所以如果本来应该绑定在click上的事件全部绑定到touchend事件上,就会出现问题。

八、参考资料

1、http://developer.telerik.com/featured/300-ms-click-delay-ios-8/

2、https://www.sitepoint.com/5-ways-prevent-300ms-click-delay-mobile-devices/

3、http://www.linovo.me/front/webapp-300ms.html

4、https://github.com/ftlabs/fastclick

5、https://github.com/filamentgroup/tappy/

6、http://labs.ft.com/2011/08/fastclick-native-like-tapping-for-touch-apps/

7、http://www.mamicode.com/info-detail-666685.html

ios的300ms点击延时问题的更多相关文章

  1. 移动浏览器Chrome 32 for Android移除300ms点击推迟

    在手机浏览器的一篇文章翻译300ms延迟实用文章,原文地址  http://updates.html5rocks.com/2013/12/300ms-tap-delay-gone-away 去掉移动设 ...

  2. 移动端300ms点击延迟

    移动端300ms点击延迟 原因:早期的苹果手机存在点击缩放,用手指在屏幕上快速双击后,iOS自带的Safari浏览器会将网页缩放至原始比例,后来很多浏览器也跟着学了. 解决方法:禁止缩放 <me ...

  3. app内嵌vue h5,安卓和ios拦截H5点击事件

    安卓和ios拦截h5点击事件,这个函数事件必须是暴漏在window下的 安卓和ios拦截普通h5函数: <div onclick = "show(),window.android.sh ...

  4. 微信公众号弹出框在IOS最新系统中点击键盘上的“完成”导致事件无法触发问题

    微信公众号弹出框在IOS最新系统中点击键盘上的"完成"导致事件无法触发问题 问题描述 微信公众号中有项功能是弹框模态框,输入信息后保存操作.但是在IOS系统中发现,当输入内容后,点 ...

  5. 李洪强iOS开发之- 点击屏幕遮挡键盘

    李洪强iOS开发之- 点击屏幕遮挡键盘 实现的效果:  01 - 给当前的view添加点击事件,使点击屏幕的时候,让键盘退出 /** * 点击屏幕 隐藏键盘 * * @param tap */-(vo ...

  6. 阻止iOS Web APP中点击链接跳转到Safari 浏览器新标签页

    问题:ios封装完之后,点击里边的按钮会跳转到网页上 ——小卡遇到这个问题就是这样解决的↓↓↓ 解决方法:建议将代码放到</head>标签前,当然,另外存为一个js 文件引用也是可以的呦~ ...

  7. ios开发图片点击放大

    图片点击放大,再次点击返回原视图.完美封装,一个类一句代码即可调用.IOS完美实现 创建了一个专门用于放大图片的类,以下为.h文件 #import <Foundation/Foundation. ...

  8. 5步解决移动设备上的300ms点击延迟

    译者:jmouse 大多数基于触摸的浏览器设备,在点击时都会有个 300ms 的事件触发等待时间,做过 web app 开发的同学应该都遇到过这个情况,通过下面的5步可以轻松搞定这个延迟. 1.不要太 ...

  9. IScroll5+在ios、android点击(click)事件不兼容解决方法

    Bug描述: ios.android4.4+下不能触发click事件. Bug解决: 调用iscroll插件,增加配置参数:click:true/false click的值是要根据移动终端设备进行判断 ...

随机推荐

  1. UIButton 之 按下高亮

    设置高亮 [btn setHighlighted:YES]; 设置按下时高亮 [btn setShowsTouchWhenHighlighted:YES];

  2. referrer vs referer

    http request里面是referer 其实是http规范拼写错了,正确的拼写应该是referrer

  3. windows中如何查看某个端口被谁占用

    说明:本人操作系统为win7 x64,文章转自http://jingyan.baidu.com/article/3c48dd34491d47e10be358b8.html,加上本人的注释. 开始--- ...

  4. js原生设计模式——9外观模式封装2(小型代码库YJ)

    <script type="text/javascript">    //小型代码库YJ封装    var YJ = {        //根据id获取元素       ...

  5. python 循环使用 while 或 for 语句实现用户名密码输错三次退出

    如有错误欢迎大家指出,新手初来乍到.程序没那么复杂,是最简单的. 一.需求 编写登录文件 .py1. 输入用户名密码2. 正确,输出欢迎登录3. 当输入用户名和密码小于 3 次,输入用户名或者密码错误 ...

  6. 我的音乐盒子(nodejs7 + koa2 + vue + vuex + vue-router)

    你们知道的,nodejs对jser来说,是个好东西,快快的,自从接触nodejs后,总想弄点东西. 这弄个啥了,一天打开百度音乐盒,哟,自己弄一个如何了,好啊好啊. 后台: nodejs 7 + ko ...

  7. 创建 OVS 外部网络 ext_net - 每天5分钟玩转 OpenStack(144)

    上一节完成连接外网的配置准备工作,今天就来创建 OVS 外部网络 ext_net. 进入 Admin -> Networks 菜单,点击 "Create Network" 按 ...

  8. ACM 刷题小技巧【转】

    转载自URl-team ACM做题过程中的一些小技巧. 1.一般用C语言节约空间,要用C++库函数或STL时才用C++; cout.cin和printf.scanf最好不要混用. 大数据输入输出时最好 ...

  9. cocos2dx内存管理的个人理解

    1.一帧开始之后的过程中,将所有执行到的autorelease的对象加入到池中:2.一帧结束之前取出池中的所有对象记作objs,清空池:3.对取出来的objs进行遍历,每个元素进行一次release: ...

  10. Android客户端连接服务器端,向服务器端发送请求HttpURLConnection

    在Java中想后台服务器发送请求一般都直接使用了Java的网络编程,或者使用HttpClient向后台服务器端发送HTTP请求.虽然在安卓中,所有Java的API都可以使用,而却使用其并不会出现什么问 ...