从移动端 click 到摇一摇
来源:互联网 发布:域名批量查询工具下载 编辑:程序博客网 时间:2024/06/05 16:04
以前听到前辈们说移动端尽量不要使用click,click会比较迟钝,能用touchstart还是用touchstart。但是用touchstart会有一个问题,用户在滑动页面的时候要是不小心碰到了相关元素也会触发touchstart,所以两者都有缺点。那怎么办呢?
首先为什么移动端的click会迟钝呢?从谷歌的开发者文档《300ms tap delay, gone away》可以找到答案:
因为移动端要判断是否是双击,所以单击之后不能够立刻触发click,要等300ms,直到确认不是双击了才触发click。所以就导致了click有延迟。
更为重要的是,文档里面还提到在2014年的Chrome 32版本已经把这个延迟去掉了,如果有一个meta标签:
<meta name="viewport" content="width=device-width">
即把viewport设置成设备的实际像素,那么就不会有这300ms的延迟,并且这个举动受到了IE/Firefox/Safari(IOS 9.3)的支持,也就是说现在的移动端开发可以不用顾虑click会比较迟钝的问题。
如果设置initial-scale=1.0,在chrome上是可以生效,但是Safari不会:
<meta name="viewport" content="initial-scale=1.0">
还有第三种办法就是设置CSS:
html{ touch-action: manipulation;}
这样也可以取消掉300ms的延迟,Chrome和Safari都可以生效。
click是在什么时候触发的呢?来研究一下click/touch事件的触发先后顺序。
1. click/touch触发顺序
click事件是在最后触发的,并且还看到300ms的延迟,实际的执行延迟要比这个大,因为浏览器的内核运行也需要消耗时间。现在加上viewport的meta标签,再观察结果,如下图所示:
可以看到,300ms的延迟没有了。
知道了click是在touchend之后触发的,现在我们来尝试一下实现一个tap事件。
2. tap事件的实现
怎么实现一个能够快速触发的tap的事件?
有两个库,一个是zepto,另一个是fastclick,它们都可以解决点击延迟的问题。
zepto有一个自定义事件tap,它是一个没有延迟的click事件。
fastclick是在touchend之后生成一个click事件,并立即触发这个click,再取消原本的click事件。
这两者的原理都是一样的,都是在touchend之后触发,一个是触发它自己定义的tap事件,一个是触发原生click。
3. 摇一摇事件
html5新增了一个devicemotion的事件,可以使用手机的重力感应。如下代码所示:
window.ondevicemotion = function(event){ var gravity = event.accelerationIncludingGravity; console.log(gravity.x, gravity.y, gravity.z);}
x,y,z表示三个方向的重力加速度,如下图所示:
x是手机短边,y是长边,z是和手机屏幕垂直的方向,当把手机平着放的时候,由于x、y和地平线平行,所以g(x) = g(y) = 0,而z和地平线垂直,所以g(z) = 9.8左右,同理当把手机竖着放的时候,g(x) = g(z) = 0,而g(y) = -9.8.
devicemotion事件会不断地触发,而且触发得很快。
当我们把手机拿起来摇一摇的时候,这个场景应该是这样的:
y轴和x轴的变化范围从-45o到+45o,即这个区间是:
delta = 9.8 * sin(45o) * 2 = 13.8
即只要x轴和y轴的g值变化超过13.8,我们就认为发生了摇一摇事件。
根据上面的分析,不难写出以下的代码:
const EMPTY_VALUE = 100;const THREAD_HOLD = 13.8;var minX = EMPTY_VALUE, minY = EMPTY_VALUE;window.ondevicemotion = function(event){ var gravity = event.accelerationIncludingGravity, x = gravity.x, y = gravity.y; if(x < minX) minX = x; if(y < minY) minY = y; if(Math.abs(x - minX) > THREAD_HOLD && Math.abs(y - minY) > THREAD_HOLD){ console.log("shake"); var event = new CustomEvent("shake"); window.dispatchEvent(event); minX = minY = EMPTY_VALUE; } } window.addEventListener("shake", function(){ console.log("window shake callback was called");});
用一个minX和minY记录最小的值,每次devicemotion触发的时候就判断当前的g值与最小值的差值是否超过了阈值,如果是的话就创建一个CustomEvent的实例,然后disatch给window,window上兼听的onshake事件就会触发了。
现在拿起手机摇一摇,控制台就会输出:
这样就实现了一个摇一摇shake事件。还有一个问题就是:这个shake会不会很容易触发,即使不是摇一摇操作它也触发了?根据实验上面代码如果不摇不容易触发shake,同时摇的时候比较容易触发。
如果太难触发可以把阈值改小点。
当然判断是否摇一摇的算法不止上面一个,你还可以想出其它更好的方法。
- 从移动端click到摇一摇
- 从移动端 click 到摇一摇
- 移动端click延迟
- 移动端的click事件
- 移动端click事件300ms延迟
- 移动端touch事件影响click事件
- 移动端-click、touch、tap、swipe事件
- 移动端WEB开发,click,touch,tap事件浅析
- 移动端touch事件影响click事件的相关解决方法
- 移动端touch事件和click事件的区别
- 移动端WEB开发,click,touch,tap事件浅析
- 移动端WEB开发,click,touch,tap事件浅析
- WEB移动端的click ,tap ,touchend事件的对比
- 移动端WEB开发,click,touch,tap事件浅析
- 移动端WEB开发,click,touch,tap事件
- 移动端web开发,click touch tap区别
- 移动端click事件延迟300ms正解大全
- 移动端WEB开发,click,touch,tap事件
- H指数(h-index)的Python实现
- centos 7的防火墙命令
- oracle行专列,求总值
- CSS垂直居中问题解决方法
- SpringBoot启动报错"Related cause: org.springframework.beans.factory.UnsatisfiedDependencyException: Err"
- 从移动端 click 到摇一摇
- Spring Cloud OAuth2、 Actuator、Docker联配最佳实践
- 4 歌曲比赛
- jQuery判断数组是否包含了指定的元素
- tensorflow在python2和python3上的安装教程
- 文章标题
- shell如何把字符串切割为数组
- luogu3388 tarjan求割点板子
- FPGA高速串行传输技术与应用—GTX概述与参考时钟篇