click300ms
初代iphone为缩放当时尚未被Mobile化的Web页面所做的历史遗留功能,如今看来也需要升级换代了。
产生原因
移动浏览器上支持的双击缩放操作,以及IOS Safari 上的双击滚动操作,是导致300ms的点击延迟主要原因。
这里提一下移动端的交互事件:
- touchstart: 手指触碰到屏幕触发
- touchmove: 手指触碰后移动触发
- touchend: 手指离开屏幕触发
- touchcancel: 系统取消touch事件的时候触发。
- click: 在这个dom(或冒泡到这个dom)上手指触摸开始,且手指未曾在屏幕上移动(某些浏览器允许移动一个非常小的位移值),且在这个在这个dom上手指离开屏幕,且触摸和离开屏幕之间的间隔时间较短(某些浏览器不检测间隔时间,也会触发click)才能触发。
上述事件发生顺序:在移动端,手指点击一个元素,会经过:touchstart --> touchmove -> touchend --》click。
双击缩放:即用手指在屏幕上快速点击两次,移动端浏览器会将网页缩放至原始比例。 那么这和 300 毫秒延迟有什么联系呢? 假定这么一个场景。用户在 浏览器里边点击了一个链接。由于用户可以进行双击缩放或者双击滚动的操作,当用户一次点击屏幕之后,浏览器并不能立刻判断用户是确实要打开这个链接,还是想要进行双击操作。因此,浏览器就等待 300 毫秒,以判断用户是否再次点击了屏幕。
解决方案
禁用缩放
对于不需要缩放的页面,通过设置meta标签禁用缩放,表明这个页面是不需要缩放的,双击缩放就没有意义了。此时浏览器可以禁用默认的双击缩放行为并且去掉300ms的点击延迟。
该方法缺点在于必须通过完全禁用缩放来达到去掉点击延迟的目的,但我们初衷是想禁止默认双击缩放行为,这样就不用等待300ms来判断当前操作是否是双击。但是通常情况下我们还是希望能通过双指缩放来进行缩放操作,比如放大图片,很小的一段文字。
FastClick
FastClick 是 FT Labs 专门为解决移动端浏览器 300 毫秒点击延迟问题所开发的一个轻量级的库。FastClick的实现原理是在检测到touchend事件的时候,会通过DOM自定义事件立即出发模拟一个click事件,并把浏览器在300ms之后的click事件阻止掉。
注意:截至2015年底,大多数移动浏览器(尤其是Chrome和Safari)不再具有300毫秒的触摸延迟,因此fastclick对新浏览器没有任何好处,并且可能会在您的应用程序中引入错误。仔细考虑您是否真的需要使用它。 from fastclick
CSS touch-action
touch-action这个属性指定了相应元素上能够触发的用户代理(也就是浏览器)的默认行为。如果将该属性值设置为touch-action: none,那么表示在该元素上的操作不会触发用户代理的任何默认行为,就无需进行300ms的延迟判断。
点击穿透问题
假如页面上有两个元素A和B。B元素在A元素之上。我们在B元素的touchstart事件上注册了一个回调函数,该回调函数的作用是隐藏B元素。我们发现,当我们点击B元素,B元素被隐藏了,随后,A元素触发了click事件。
这是因为在移动端浏览器,事件执行的顺序是touchstart > touchend > click。而click事件有300ms的延迟,当touchstart事件把B元素隐藏之后,隔了300ms,浏览器触发了click事件,但是此时B元素不见了,所以该事件被派发到了A元素身上。如果A元素是一个链接,那此时页面就会意外地跳转。
解决方案:
只用touch,把页面被全部click换成touch事件(touchstart、touchend、tap)。
需要特别注意a标签,a标签的href也是click,需要去掉换成js控制的跳转,或者直接改成span + tap控制跳转。如果要求不高,不在乎滑走或者滑进来触发事件的话,span + touchend就可以了,毕竟tap需要引入第三方库不用a标签其实没什么,移动app开发不用考虑SEO,即便用了a标签,一般也会去掉所有默认样式,不如直接用span。
代码上处理建议:在touchend事件上调用 preventDefault()在一次成功的点击后,建议接下来的 500ms 以内取消所有的 click 事件。分析点击事件,判断如果是慢速点击穿透,则取消所有 click 事件,如果是快速点击穿透,取消触摸事件 50ms以内的 click 事件即可。别的参考思路(开源库fastclick),取消 click 事件,用touchend 模拟 快速点击行为。
移动端300ms点击延迟和点击穿透
300 毫秒点击延迟的来龙去脉
hammer.js
- 用于检测触摸手势的 JavaScript 库
- 添加对触摸手势的支持并移除了点击的 300ms
-
支持最常见的单点和多点触摸手势,并且可以完全扩展以添加自定义手势
安装
- NPM:npm install --save hammer.js
- CDN:https://cdnjs.com/libraries/hammer.js/
Tap
在指定的 DOM 区域内,一个手指轻拍或点击时触发该事件(类似 PC 端的 click),该事件最大点击时间为 250ms,如果超过 250ms 则按 press 事件处理
press
在指定的 DOM 区域内,这个事件相当于 PC 端的 Click 事件,不能包含任何的移动,最小按压时间为 500ms,常用于我们在手机上用的复制粘贴等功能
该事件事分别对以下事件进行监听并处理
pressup: 点击事件离开时触发
pan
在指定的 DOM 区域内,一个手指放下并移动事件,即触屏中的拖动事件。
该事件事分别对以下事件进行监听并处理
panstart: 拖动开始
panmove: 拖动过程
panend: 拖动结束
pancancel: 拖动取消
panleft: 向左拖动
panright: 向右拖动
panup: 向上拖动
pandown: 向下拖动
swipe
该事件事分别对以下事件进行监听并处理
swipeleft: 向左滑动
swiperight: 向右滑动
swipeup: 向上滑动
swipedown: 向下滑动
pinch
在指定的 DOM 区域内,两个手指(默认为两个手指,多指触控需要单独设置)或多个手指相对(越来越近)移动或相向(越来越远)移动时事件
该事件事分别对以下事件进行监听并处理
pinchstart: 多点触控开始
pinchmove: 多点触控过程
pinchend: 多点触控结束
pinchcancel: 多点触控取消
pinchin: 多点触控时两手指越来越近
pinchout: 多点触控时两手指越来越远
rotate
在指定的 DOM 区域内,当两个手指或更多手指呈圆型旋转时触发
该事件事分别对以下事件进行监听并处理
rotatestart: 旋转开始
rotatemove: 旋转过程
rotateend: 旋转结束
rotatecancel: 旋转取消
HAMMER.JS中文
Hammer.js 中文教程(有 demo)
iScroll
iScroll是一个高性能,资源占用少,无依赖,多平台的javascript滚动插件。
它可以在桌面,移动设备和智能电视平台上工作。它一直在大力优化性能和文件大小以便在新旧设备上提供最顺畅的体验。
iScroll不仅仅是 滚动。它可以处理任何需要与用户进行移动交互的元素。在你的项目中包含仅仅4kb大小的iScroll,你的项目便拥有了滚动,缩放,平移,无限滚动,视差滚动,旋转功能。给它一个扫帚它甚至能帮你打扫办公室。
即使平台本身提供的滚动已经很不错,iScroll可以在此基础上提供更多不可思议的功能。具体来说:
- 细粒度控制滚动位置,甚至在滚动过程中。你总是可以获取和设置滚动器的x,y坐标。
- 动画可以使用用户自定义的擦出功能(反弹'bounce',弹性'elastic',回退'back',...)。
- 你可以很容易的挂靠大量的自定义事件(onBeforeScrollStart)
- 开箱即用的多平台支持。从很老的安卓设备到最新的iPhone,从Chrome浏览器到IE浏览器。
例子
Document
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 16
- 16
- 16
- 16
- 16
- 16
- 16
- 16
- 16
- 16
- 16
- 16
- 16
- 16
- 16
- 16
- 16
- 16
- 16
- 16
- 16
iScroll5 API中文版
iScroll - 3秒變成iPhone,模擬拖曳反彈(bounds)神器
iscroll.js的使用
其他整理
mobileTech
【原】移动web资源整理